Multiple identical #defines and C function declarations

R

Richard

1. Are there any problems with having, for instance, POSIX's "open"
function #defined more than once. In my case, these would be in
different static libraries:

#ifdef __cplusplus
extern "C" {
#endif

#define open myOpenFunction1

#ifdef __cplusplus
}
#endif

-and-

#ifdef __cplusplus
extern "C" {
#endif

#define open myOpenFunction2

#ifdef __cplusplus
}
#endif

2. Different way of doing the same thing... Are there any problems
with having the same code to #define open as myOpenFunction1 (only
#define once this time), but have two implementations (definitions) of
myOpenFunction1? I've seen linking issues due to multiply defined
symbols before, but this seems to pass with the linker. Both
definitions are in 'extern "C"' - is that why the compiler isn't
complaining, or is it simply because one of them isn't linked for one
reason or another?
 
G

Gianni Mariani

Richard said:
1. Are there any problems with having, for instance, POSIX's "open"
function #defined more than once. In my case, these would be in
different static libraries:

Let's assume you can.

#define open X
#define open Y

open <-- what do you want open to expand to now ?
 
L

Larry Smith

Richard said:
1. Are there any problems with having, for instance, POSIX's "open"
function #defined more than once. In my case, these would be in
different static libraries:

#ifdef __cplusplus
extern "C" {
#endif

#define open myOpenFunction1

#ifdef __cplusplus
}
#endif

-and-

#ifdef __cplusplus
extern "C" {
#endif

#define open myOpenFunction2

#ifdef __cplusplus
}
#endif

2. Different way of doing the same thing... Are there any problems
with having the same code to #define open as myOpenFunction1 (only
#define once this time), but have two implementations (definitions) of
myOpenFunction1? I've seen linking issues due to multiply defined
symbols before, but this seems to pass with the linker. Both
definitions are in 'extern "C"' - is that why the compiler isn't
complaining, or is it simply because one of them isn't linked for one
reason or another?

The preprocessor handles "#define" statements.
They are merely text replacements; the compiler never
sees them.

So in once case, every occurence of "open" is replaced
with "myOpenFunction1" BEFORE the code is passed to the
compiler. In the other case, every occurence of "open"
is replaced with "myOpenFunction2" BEFORE the code is
passed to the compiler.

So, the compiler & linker only see "myOpenFunction1"
and "myOpenFunction2".
 
R

Richard

I agree fully with Larry about #1. I believe it to be legal to have
multiple #defines of "open", but it does boil down to text
replacement. In my case, I want all usages of "open" to resolve to
the same function, so this option is out of the question.

#2, seems to do the trick, though I'm not sure if it's because the
linker is lenient. In one library a function is defined in 'extern
"C"' and declared. In another library a function with the same name
and signature is defined the same way. When I link these libraries
into an executable, either of the functions ends up being used based
on what the linking order was!

Any ideas why the linker doesn't complain there are "multiply defined
symbols"? I tried defining a function in this manner twice in the
same file, and the compiler catches this. But when they are in
different libraries, it gets past both the compiler and the linker.
 
L

Larry Smith

Richard said:
I agree fully with Larry about #1. I believe it to be legal to have
multiple #defines of "open", but it does boil down to text
replacement. In my case, I want all usages of "open" to resolve to
the same function, so this option is out of the question.

#2, seems to do the trick, though I'm not sure if it's because the
linker is lenient. In one library a function is defined in 'extern
"C"' and declared. In another library a function with the same name
and signature is defined the same way. When I link these libraries
into an executable, either of the functions ends up being used based
on what the linking order was!

Any ideas why the linker doesn't complain there are "multiply defined
symbols"? I tried defining a function in this manner twice in the
same file, and the compiler catches this. But when they are in
different libraries, it gets past both the compiler and the linker.

Once the Linker finds a match it quits searching (i.e. it does not
look in any other object files or libs for that symbol).
 
L

Larry Smith

Larry said:
Once the Linker finds a match it quits searching (i.e. it does not
look in any other object files or libs for that symbol).

Well, that's not a 'blanket statement'.
It depends on the OS & Linker, but many work that way.
 
J

James Kanze

I agree fully with Larry about #1. I believe it to be legal to have
multiple #defines of "open", but it does boil down to text
replacement. In my case, I want all usages of "open" to resolve to
the same function, so this option is out of the question.
#2, seems to do the trick, though I'm not sure if it's because the
linker is lenient. In one library a function is defined in 'extern
"C"' and declared. In another library a function with the same name
and signature is defined the same way. When I link these libraries
into an executable, either of the functions ends up being used based
on what the linking order was!
Any ideas why the linker doesn't complain there are "multiply defined
symbols"?

Because you didn't include both object files in the program?

Symbols aren't in libraries, they are in object files (the
results of a compilation). A library is a collection of object
files, which the linker conditionally includes in your program:
if the object file defines a symbol which corresponds to an
unresolved external, the linker pulls it out of the library, and
adds it to your program. If it doesn't, the linker just ignores
it.
I tried defining a function in this manner twice in the
same file, and the compiler catches this. But when they are in
different libraries, it gets past both the compiler and the linker.

That's more or less the definition of a library. You can still
get multiple definitions, however: objA.o defines a and c,
objB.o defines b and c. Put them in a library, and specify it
when linking a program with undefined symbols a and b.

The important thing to remember when using libraries is that
they are only sets of object files, and that the inclusion of
the object file is conditional. If you have object files that
you absolutely want in your program, you can't put them in a
library; you have to specify them explicitly, as object files.
 

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,774
Messages
2,569,596
Members
45,143
Latest member
DewittMill
Top