Why does Borland compile with multiple definitions of same object in different C files while GCC does not?
Asked Answered
L

1

5

I am studying the behavior of global variables.

So far , I thought the multiple definition of global variables is an illegal way , and must get an error. But I got an unexpected result from Borland C/C++ compiler , while GCC gave me the expected result.

Code:

test1.c:

#include<stdio.h>

void func(void);

int num=1;

void main(){
    func();
    return;
}

test2.c:

#include<stdio.h>

int num=2;

void func(){    
    printf("%d",num);
    return;
}

On MS-DOS prompt

  • Borland C/C++ :

    c:\test>bcc32 test1.c test2.c
    
  • GCC :

    c:\test>gcc test1.c test2.c
    

Results

  • Borland C/C++ :

There's no error and compile&link successfully(This is unexpected for me).After executing test1.exe , 2 was printed on the console. This is num's value defined in test2.c.

  • GCC :

GCC gave me an error of multiple definition of num. Of course , a.exe was not made.(This is what I was expecting)

Why does that happen? Please let me know. Thank you!

Lumbye answered 27/12, 2014 at 12:36 Comment(3)
Which version of compilers? Which operating system? For GCC you should compile at least with gcc -Wall -Wextra -gImperturbable
Because most people want to debugImperturbable
Trying things and seeing what happens isn't a good way to study C or C++, because you don't know whether or not you are seeing undefined behaviourFelicity
L
8

Multiple external definitions of an object is undefined behavior in C. A common extension is to accept multiple definitions if they don't disagree (usually with same type and no initialization value).

C99 6.9p5 says:

If an identifier declared with external linkage is used in an expression (other than as part of the operand of a sizeof operator whose result is an integer constant), somewhere in the entire program there shall be exactly one external definition for the identifier; otherwise, there shall be no more than one"

and C99, 4.p2:

violation of a "shall" outside of a constraint implies UB

Leveille answered 27/12, 2014 at 12:38 Comment(7)
I think there will be a compiler warning if we have something like this in our code since there is a single instance of num?Mimi
@Mimi ld linker option --warn-common will warn if multiple common symbols for the same variable are merged.Leveille
Related info: no external definition is also UB, no diagnostic required; and the same thing applies to functions. Linkers often do better than the minimum requirement but this leeway exists to allow for various linking setups, e.g. look up "weak symbols".Felicity
C99 quote pleaase :-)Catfish
@CiroSantilli六四事件法轮功包卓轩 (C99, 6.9p5) "If an identifier declared with external linkage is used in an expression (other than as part of the operand of a sizeof operator whose result is an integer constant), somewhere in the entire program there shall be exactly one external definition for the identifier; otherwise, there shall be no more than one" You are welcome.Leveille
Ah, so that wording imply UB? So that is why grepping that section did not work :-)Catfish
@CiroSantilli六四事件法轮功包卓轩 violation of a "shall" outside of a constraint implies UB (see C99, 4.p2).Leveille

© 2022 - 2024 — McMap. All rights reserved.