This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

MULTIPLE PUBLIC DEFINITIONS ?

i write a global.h file:

#ifndef GLOBAL_H
#define GLOBAL_H

int nGlobal;
#endif

//file A.c
#include "global.h"
....

//file B.c
#include "global.h"
....

Build target 'Target 1'
compiling A.c...
compiling B.c...
linking...
*** ERROR L104: MULTIPLE PUBLIC DEFINITIONS
SYMBOL: nGLOBAL
MODULE: A.obj
*** ERROR L104: MULTIPLE PUBLIC DEFINITIONS
SYMBOL: nGLOBAL
MODULE: B.obj

oh,why the error do not happen when i write code "#include <reg51.h>" in several .c files.
please help me,thank you very much.

Parents
  • "int a" tells the compiler to reserve space for an integer.

    Close, yet not quite completely correct. The statements

    int a = 0;
    int b = some_value;
    do indeed and unquestionably reserve space for an integer (and initialize it), right then and there. But the case of
    int a;
    without an initializer is trickier.

    This is what the standard calls a tentative definition. That's to say it is interpreted as just a declaration, i.e. as if you had written
    extern int a;
    until the compiler has finished with the source file in question. If, and only if there was no initialized definition of the object found until then, the tentative definition is turned into a real definition, and will actually reserve space. That's how it comes that
    int a;
    int a;
    int a = 5;
    is allowed, while
    int a = 5;
    int a = 5;
    isn't.

    And to make matters worse, the C language definition leaves it open to the implementor to decide what happens if two separate compilation units (vulgo: source files) both contain only tentative definitions of a same-named object. Most Unix-born C toolchains out there will happily accept a program that has
    int a;
    in a header #include'd by several source files --- they'll just join all these tentative definitions into a single object, thus extending the tentative status of the definition beyond the source file's compile time, until the time the whole program is linked.

Reply
  • "int a" tells the compiler to reserve space for an integer.

    Close, yet not quite completely correct. The statements

    int a = 0;
    int b = some_value;
    do indeed and unquestionably reserve space for an integer (and initialize it), right then and there. But the case of
    int a;
    without an initializer is trickier.

    This is what the standard calls a tentative definition. That's to say it is interpreted as just a declaration, i.e. as if you had written
    extern int a;
    until the compiler has finished with the source file in question. If, and only if there was no initialized definition of the object found until then, the tentative definition is turned into a real definition, and will actually reserve space. That's how it comes that
    int a;
    int a;
    int a = 5;
    is allowed, while
    int a = 5;
    int a = 5;
    isn't.

    And to make matters worse, the C language definition leaves it open to the implementor to decide what happens if two separate compilation units (vulgo: source files) both contain only tentative definitions of a same-named object. Most Unix-born C toolchains out there will happily accept a program that has
    int a;
    in a header #include'd by several source files --- they'll just join all these tentative definitions into a single object, thus extending the tentative status of the definition beyond the source file's compile time, until the time the whole program is linked.

Children
No data