global variable name conflict with standard header

V

Vadim Biktashev

Hello all
I would like to give a certain name to a certain global variable. Unfortunately,
this name is already used in math.h for a mathematical function. Worse, I do
need to use maths library and therefore have to include math.h. Thus my compiler
reports conflicting declarations of the same name.
Does anyone know any reasonably elegant way to resolve this conflict? I
understand that I can give up and choose another name, but somehow not happy
with that.
Any advice would be much appreciated!
- V.
 
E

Emmanuel Delahaye

Vadim Biktashev wrote on 11/08/04 :
I would like to give a certain name to a certain global variable.
Unfortunately, this name is already used in math.h for a mathematical
function. Worse, I do need to use maths library and therefore have to include
math.h. Thus my compiler reports conflicting declarations of the same name.
Does anyone know any reasonably elegant way to resolve this conflict? I
understand that I can give up and choose another name, but somehow not happy
with that.

No way, you have to change the name. The usual trick is to add some
meaningful prefix

PREFIX_identifier

(BTW, it's not a C question)
 
R

Richard Bos

Emmanuel Delahaye said:
Vadim Biktashev wrote on 11/08/04 :

No way, you have to change the name. The usual trick is to add some
meaningful prefix

PREFIX_identifier

(BTW, it's not a C question)

Yes, it is: you cannot have two conflicting declarations of the same
identifier, hence the problem. Of course, the answer is "don't do that,
then", but that doesn't make the question off-topic.

Richard
 
V

Vadim Biktashev

Richard said:
Yes, it is: you cannot have two conflicting declarations of the same
identifier, hence the problem. Of course, the answer is "don't do that,
then", but that doesn't make the question off-topic.

Richard


Perhaps, I was not precise enough.

The question is: is there any way to cancel a definition/declaration made
earlier, apart from opening a block and making a new definition local in that
block. My naive logic was, if it is possible for macros, why not make a similar
thing for regular C names.

- Vadim
BTW if this is really not for this newsgroup, perhaps a kind soul could direct
me to the right one?
 
E

Emmanuel Delahaye

Richard Bos wrote on 11/08/04 :
Yes, it is: you cannot have two conflicting declarations of the same
identifier, hence the problem. Of course, the answer is "don't do that,
then", but that doesn't make the question off-topic.

Ok. I meant that it's not specific to C.
 
E

Eric Sosman

Vadim said:
>
> [Wants to give a global variable the same identifier as
> a Standard library function]

The question is: is there any way to cancel a definition/declaration
made earlier, apart from opening a block and making a new definition
local in that block. My naive logic was, if it is possible for macros,
why not make a similar thing for regular C names.

Because macro identifiers have no linkage.

"Linkage" is the magic that takes an identifier that
appears in several different scopes and makes all those
different appearances refer to the same object or function:

/* file1.c */
int myValue = 42;
...

/* file2.c */
void func(void) {
extern int myValue;
...
}

Here we have two occurrences of the identifier `myValue'
each with its own scope. The scope of the first covers
all of file1.c from the point of declaration to the end.
The scope of the second is limited to the body of func();
the identifier is not "visible" outside the block.

But when the two files are combined into a single
program, both `myValue' identifiers are made to refer to
the same `int' variable. This process of coalescing
identically-named externally-linked identifiers into a
single entity is driven entirely by their names: If two
externally-linked identifiers have the same spelling, they
are combined to refer to the same object or function.

... which means that if you try to use the same
externally-linked name for two or more different things,
the association of "name" to "thing" breaks down. The
process of linking identifiers together depends on those
identifiers being unique[*], and if they aren't ... The
linker will have no way to resolve the conflict between
"different" identically-named identifiers, and Something
Bad will happen. (Some linkers will detect the problem,
some will detect it only in certain circumstances, and
some will not detect it at all but will give you a program
that doesn't do what you want.)

[*] For externally-linked identifiers there are even
stronger restrictions: Some linkers may consider only the
first N characters of an identifier, and some may treat
upper- and lower-case letters as identical. The details
of these additional restrictions depend on which Standard
("C89/90" or "C99") your implementation conforms to.
 
C

CBFalconer

Emmanuel said:
Vadim Biktashev wrote on 11/08/04 :


No way, you have to change the name. The usual trick is to add
some meaningful prefix

PREFIX_identifier

(BTW, it's not a C question)

Yes it is. The standard specifically forbids reusing any
identifier exported from any standard include file used, under
penalty of undefined behavior.

The underlying reason is that something in the library may be of
the form:

foo(fee)

and get used by another library portion that calls foo. If the
name has been redefined somehow, that call goes to the wrong
place. For example, if you #include <stdlib.h> and write your own
routine malloc(), the library routine for malloc may not get
loaded. However the realloc() routine may well call the original
malloc, and if rerouted its assumptions are no longer valid. All
of these may be called behind your back in the initialization
code.

So don't do that.
 
A

Arthur J. O'Dwyer

Emmanuel said:
Vadim Biktashev wrote on 11/08/04 :
I would like to give a certain name to a certain global variable.
Unfortunately, this name is already used in math.h for a
mathematical function.
[...]
(BTW, it's not a C question)

Yes it is. The standard specifically forbids reusing any
identifier exported from any standard include file used, under
penalty of undefined behavior.

The underlying reason is that something in the library may be of
the form:

foo(fee)

and get used by another library portion that calls foo. If the
name has been redefined somehow, that call goes to the wrong
place. For example, if you #include <stdlib.h> and write your own
routine malloc(), the library routine for malloc may not get
loaded. However the realloc() routine may well call the original
malloc, and if rerouted its assumptions are no longer valid. All
of these may be called behind your back in the initialization
code.

Amplification: It's not just the library-linkage problem. We
have sentences in the Standard that say explicitly things like

[#3] The implementation shall behave as if no library
function calls the rand function.

and yet it's /still/ UB to define 'extern int rand;'. This may be
for the benefit of dumb optimizers who can now inline any standard
library routine they like, without checking symbol tables or whatnot.
So for instance GCC can convert calls to 'memcpy' into inline
assembler, even if you've already defined

double memcpy(double m); // Copy the magnitude of exp^m

somewhere else.

-Arthur
 
E

Eric Sosman

Arthur said:
Amplification: It's not just the library-linkage problem. We
have sentences in the Standard that say explicitly things like

[#3] The implementation shall behave as if no library
function calls the rand function.

and yet it's /still/ UB to define 'extern int rand;'. This may be
for the benefit of dumb optimizers who can now inline any standard
library routine they like, without checking symbol tables or whatnot.
> [...]

Another reason is that the library implementation may
need "private" or "internal" interfaces to do its job. This
is most not likely the case with rand(), but is almost certainly
so in other areas. For example, exit() must close all open
streams, implying that there must be some kind of sub rosa
information sharing with fopen() and fclose().

The memory management functions are perhaps the "most
overridden" in the Standard library, because replacing them
can be so helpful in detecting certain kinds of bugs. No
one would be foolish enough to replace malloc() without also
replacing calloc() and realloc() and free(), but even if you
carefully replace all four of them, what are you going to do
about the private and undocumented _allocate_aligned() function,
used by fopen() to allocate stream buffers? The real fun starts
when fclose() calls the replacement free() to release a buffer
that the associated malloc() has never heard of ...

The Standard is often described as a contract between the
implementor and the user. Another word might be "frontier:"
the programmer stays on *this* side and the implementor stays
on *that* side, and all will be well. Just as the implementor
is forbidden to intrude on the user's turf by, say, adding
extraneous declarations to <stdlib.h>, the user is forbidden
to trespass on the implementor's turf by redefining longjmp().
C's border guards carry UBs instead of Uzis, but they can be
equally deadly.
 
P

pete

Vadim said:
Hello all
I would like to give a certain name to a certain global variable.
Any advice would be much appreciated!

The first question that comes to my mind is,
is that certain name, a reserved identifier?

(In other words, "Which name?")
 
R

Richard Bos

Emmanuel Delahaye said:
Richard Bos wrote on 11/08/04 :

Ok. I meant that it's not specific to C.

Not completely, but it's not a completely general problem, either. Many
languages have ways to specify the namespace of an identifier, allowing
you to do what the OP wants to do. C does not. It's true that C isn't
the only language which doesn't; but that alone doesn't make it
off-topic.

Richard
 
R

Richard Bos

Arthur J. O'Dwyer said:
place. For example, if you #include <stdlib.h> and write your own
routine malloc(), the library routine for malloc may not get
loaded. However the realloc() routine may well call the original
malloc, and if rerouted its assumptions are no longer valid. All
of these may be called behind your back in the initialization
code.

Amplification: It's not just the library-linkage problem. We
have sentences in the Standard that say explicitly things like

[#3] The implementation shall behave as if no library
function calls the rand function.

and yet it's /still/ UB to define 'extern int rand;'. This may be
for the benefit of dumb optimizers who can now inline any standard
library routine they like, without checking symbol tables or whatnot.

Not just that. It would be allowed, for example, to
- save the state of rand();
- call rand() to get a random number;
- restore the previous state.
If the programmer can replace rand(), this is no longer possible.

Of course, this is hardly likely to be useful with rand() itself; but it
is a possibility.

Richard
 
C

CBFalconer

Richard said:
.... snip ...

Not completely, but it's not a completely general problem, either.
Many languages have ways to specify the namespace of an identifier,
allowing you to do what the OP wants to do. C does not. It's true
that C isn't the only language which doesn't; but that alone
doesn't make it off-topic.

Yes, C does have namespaces. To grossly simplify, anything
starting with a '_' is in system space, and most ordinary
identifiers are in user space. They just aren't named
namespaces. struct and enum tags are another area.
 
M

Malcolm

pete said:
The first question that comes to my mind is,
is that certain name, a reserved identifier?

(In other words, "Which name?")
It would be a sin to tell you.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,009
Latest member
GidgetGamb

Latest Threads

Top