1

Scenario 1: I want to link an new library (libA) into my program, libA was built using gcc with -std=gnu99 flag, while the current libraries of my program were built without that option (and let's assume gcc uses -std=gnu89 by default).

Scenario 2: libB was built with some preprocessor flags like "-D_XOPEN_SOURCE -D_XOPEN_SOURCE_EXTENDED" to enable XPG4 features, e.g. msg_control member of struct msghdr. While libC wasn't built without those preprocessor flags, then it's linked against libB.

Is it wrong to link libraries built with different preprocessor flags or C standards ? My concern is mainly about structure definitions mismatch.

Thanks.

vantaa
  • 15
  • 5
  • I do this a lot for different optimizations, with a critical routine optimized more finely than the rest of the program. – Mikhail Jan 24 '13 at 08:27
  • Thanks Mikhail, yes I understand it should work in the case of different optimization flags. I've updated my question, what I worry is about structure definitions mismatch. – vantaa Jan 24 '13 at 08:38

2 Answers2

0

The few times I have encountered structure definition mismatch was when combining C and C++ code, in these cases there was a clear warning that something terrible was happening. Something like

/usr/lib/gcc/i586-suse-linux/4.3/../../../../i586-suse-linux/bin/ld: Warning: size of symbol `tree' changed from 324 in /tmp/ccvx8fpJ.o to 328 in gpu.o

See that question.

Community
  • 1
  • 1
Mikhail
  • 7,749
  • 11
  • 62
  • 136
  • Interesting, I did a experiment but see no such warning. however my experiment used C and gcc only. – vantaa Jan 24 '13 at 09:10
0

Scenario 1 is completely safe for you. std= option in GCC checks code for compatibility with standard, but has nothing to do with ABI, so you may feel free to combine precompiled code with different std options.

Scenario 2 may be unsafe. I will put here just one simple example, real cases may be much more tricky.

Consider, that you have some function, like:

#ifdef MYDEF
int foo(int x) { ... }
#else
int foo(float x) { ... }
#endif

And you compile a.o with -DMYDEF and b.o without, and function bar from a.o calls function foo in b.o. Next you link it together and everything seems to be fine. Then everything fails in runtime and you may have very hard time debugging why are you passing int from one module, while expecting float on callee side.

Some more tricky cases may include conditionally defined structure fields, calling conventions, global variable sizes.

P.S. Assuming all your sources are written in the same language, varying only std options and macro definitions. Combining C and C++ code is really tricky sometimes, agree with Mikhail.

Konstantin Vladimirov
  • 6,791
  • 1
  • 27
  • 36