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.