2

I have seen a code where there was declared a char array in a header file and the header was included in two files.

// header
char lookup[255];

I thought there should be some linker error for two definitions of array of the same name and I should be declare it and define it in a .c file and put extern in the header.

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
  • I'm sorry, but I don't follow what your question is here--are you asking why there was no linker error as you expected? – ggorlen Dec 17 '18 at 23:34
  • yes, if i compile it into binary, i dont get any error and it seems both .c files use the same char array. –  Dec 17 '18 at 23:43
  • 1
    See the discussion of 'the common extension' in [How do I use `extern` to share variables between source files?](https://stackoverflow.com/questions/1433204/how-do-i-use-extern-to-share-variables-between-source-files) You're right; strict standard conformance would expect an error, but the standard itself notes that it is a 'common extension' in C11 [§J.5.11 Multiple external definitions](http://port70.net/~nsz/c/c11/n1570.html#J.5.11). – Jonathan Leffler Dec 17 '18 at 23:52
  • @JonathanLeffler You would hope for at least a warning if compiling with `-Wall -Wextra -pedantic` – Christian Gibbons Dec 18 '18 at 00:22
  • 1
    @ChristianGibbons: It's tough for a single TU (translation unit) to identify problems which are only a problem when multiple TUs are linked together. Sadly, it not easy for the compiler to diagnose the issue at all. Now, if you asked for a loader/linker option to identify it, then yes — it might be useful. – Jonathan Leffler Dec 18 '18 at 00:24
  • @JonathanLeffler Ah, yes, that makes sense. – Christian Gibbons Dec 18 '18 at 00:29

2 Answers2

1

Do not put any actual data or code into the header files. There are some exceptions like static inline functions, but as rule of thumb: in header files only declarations and types, in .c files definitions

0___________
  • 60,014
  • 4
  • 34
  • 74
0

The compiler will compile each .c file independently, not knowing that it was already included in another file. But you will get a linker error as soon as you try to link the compiled object files together.

With gcc, the following works:

gcc -c include1.cpp include2.cpp

But linking fails:

gcc -o include include1.o include2.o
/usr/lib64/gcc/x86_64-suse-linux/8/../../../../x86_64-suse-linux/bin/ld: include2.o:(.bss+0x0): multiple definition of `lookup'; include1.o:(.bss+0x0): first defined here
collect2: error: ld returned 1 exit status
Georg
  • 94
  • 4
  • The question isn't so worried about it being included twice in the same translation unit, but rather being included by two different .c files. – Christian Gibbons Dec 17 '18 at 23:17
  • OT: identifiers beginning with and underscore should be avoided since they are reserved. – Osiris Dec 17 '18 at 23:19
  • my question is rather how come it's possible that it is included in two different .c files and compiles just fine. –  Dec 17 '18 at 23:22
  • @Osiris I believe it is only reserved if the leading underscore is followed by a second underscore or a capital letter. In this case, it was followed by a capital, so it was indeed reserved. – Christian Gibbons Dec 17 '18 at 23:26
  • Note that by compiling `.cpp` files, you've used the C++ rules, one of which is the ODR (one definition rule). On some systems (Linux for example), there's a linker option `-Wl,-relax` that might allow it to link. However, using C++ when answering a C question isn't all that helpful. – Jonathan Leffler Dec 18 '18 at 00:38
  • Note that you should not, in general, create function, variable, tag or macro names that start with an underscore. Part of [C11 §7.1.3 Reserved identifiers](https://port70.net/~nsz/c/c11/n1570.html#7.1.3) says: — _All identifiers that begin with an underscore and either an uppercase letter or another underscore are always reserved for any use._ — _All identifiers that begin with an underscore are always reserved for use as identifiers with file scope in both the ordinary and tag name spaces._ See also [What does double underscore (`__const`) mean in C?](https://stackoverflow.com/a/1449301) – Jonathan Leffler Dec 18 '18 at 00:39