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

Does the #ifndef to prevent recursive inclusion actually work ?

I am experimenting with the Keil MDK-ARM toolchain (the free version), and an STM32F407 Discovery board.
So far so good, were it not for a small problem. My background is with Embarcadero RAD Studio C++Builder, and with it I often use these starting lines in a header file :

#ifndef __THIS_HEADER
 #define __THIS_HEADER
.....
 float myarray[128];
#endif

This to prevent that including this header in more than one source file causes an
error of multiple definition of the variable myarray.

If I do the same with the uVision compiler, the linker complains loudly about
myarray being multiple defined...

Does the uVision compiler behaves differently than the RAD Studio compiler ?

Thanks,

-Fred

  • 1) That leading __ in your identifier means that you are writing system code. Are you sure that it is you who are writing the C runtime library code? Symbols that start like that belongs to a reserved name space.

    2) Include protection is not to protect from two source files (which normally means *.c, *.cpp) from including the same header file. It is to allow header files to include other header files and still allow another header file or the source file to also include the same header file. But multiple source files can include the same header file without include protection, since each source file is its own compilation unit. That also means that a source file (*.c) should not include another source file. It should only include header files. And header files should not include source files. Only header files.

    3) Include protection works in the Keil compilers too. Make sure you haven't spelled something wrong.

    4) You don't make use of the "extern" keyword in your header file. Are you really sure you know the difference between a definition and a declaration?

    Consider having:

    my_header.h:

    extern int my_variable;
    

    my_source.c:

    #include "my_header.h"
    int my_variable;
    

    my_other_source.c:

    #include "my_header.h"
    
    void my_function(void) {
        my_variable = 5;
    }
    

    Or if you really want to define and declare in the same header file:

    my_header.h:

    #if defined(GLOBALS)
    #define EXTERN extern
    #else
    #define EXTERN
    #endif
    
    EXTERN int my_variable;
    

    my_source.c:

    #define GLOBALS
    #include "my_header.h"
    
    ...
    

    my_other_source.c:

    #include "my_header.h"
    
    ...
    

  • Thanks to who answered. The key phrase is the following :

    Include protection is not to protect from two source files (which normally means *.c, *.cpp) from including the same header file. It is to allow header files to include other header files and still allow another header file or the source file to also include the same header file. But multiple source files can include the same header file without include protection, since each source file is its own compilation unit.

    I thought that the include protection worked across multiple source files.
    This seems to not be the case. All clear now, thanks.

    -Fred

  • That does seem to be quite a common misconception.