简体   繁体   中英

Multiple includes of same header file in project: C vs C++

Here I have an example project with two source files and a header file, as follows:

main.c:

#include<stdio.h>                                                               
#include "personal.h"                                                           
int main(){                                                                     
    i = 5;                                                                        
    printf("Value is %d\n",i);                                                    
    return 0;                                                                     
 }

sub.c:

#include "personal.h"                                                           
// do nothing

and finally personal.h:

#pragma once                                                                    
int i; 

Each of the.c file includes the personal.h, which is `guarded'. I compile with gcc, all goes fine:

>gcc sub.c main.c -o out
>./out 
Value is 5

But with g++, this happens:

>g++ sub.c main.c -o out
/tmp/cctYwVnO.o:(.bss+0x0): multiple definition of `i'
/tmp/ccPElZ27.o:(.bss+0x0): first defined here
collect2: error: ld returned 1 exit status

Is there anything fundamentally different between C++ and C in terms of how files are linked, preprocessor activity etc? I tried the same with other compilers like clang and the same happens. I am perhaps missing something silly here.

In C,

int i;

is a tentative definition. By the virtue of inclusion, you have a tentative definition for i in two compilation units. The C standard allows to have tentative definitions in multiple compilation units, but does not mandate that implementation accept that. The custom behavior for Unix C compilers is to allow it but gcc has an option ( -fno-common ) to prevent it and generate an error at link time (so that you can check the code for compilers, as I think Microsoft one, which does not allow it or for platforms for which that allow better code -- I know of none but that's a rationale given by GCC documentation).

IIRC, C++ has no such allowance.

Note that you probably want a declaration and not a definition in headers. Thus for the i above it should be

extern int i;

in the header and one

int i;

at global scope in one .c file.

sub.c will include personal.h and will create the variable i in global scope. Similarly, main.c will also include personal.h and create variable i in global scope. Eventually, when you link, there are two definitions of i in the global scope and hence the error.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM