在c ++中编译但在c(gcc)中编译时复杂

tra*_*ang 6 c c++ gcc compiler-errors g++

我在c ++中有乘法声明的问题,但在c中却没有.您可以查看代码以获取更多信息.

文件main.c

#ifndef VAR
#define VAR
int var;
#endif
int main(){}
Run Code Online (Sandbox Code Playgroud)

文件other.c

#ifndef VAR
#define VAR
int var;
#endif
Run Code Online (Sandbox Code Playgroud)

用gcc编译

gcc main.c other.c
>> success
Run Code Online (Sandbox Code Playgroud)

用g ++编译

g++ main.c other.c
Output:
/tmp/ccbd0ACf.o:(.bss+0x0): multiple definition of `var'
/tmp/cc8dweC0.o:(.bss+0x0): first defined here
collect2: ld returned 1 exit status
Run Code Online (Sandbox Code Playgroud)

我的gcc和g ++版本:

gcc --version
gcc (Ubuntu/Linaro 4.6.3-1ubuntu5) 4.6.3
Copyright (C) 2011 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

g++ --version
g++ (Ubuntu/Linaro 4.6.3-1ubuntu5) 4.6.3
Copyright (C) 2011 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
Run Code Online (Sandbox Code Playgroud)

AnT*_*AnT 12

由于变量的多个定义,您的代码在C和C++中都是正式错误的var.只是这种类型的错误传统上被C编译器忽略为一种流行的非标准扩展.在C语言规范中甚至提到了这个扩展

J.5常用扩展

以下扩展在许多系统中广泛使用,但不能移植到所有实现.[...]

J.5.11多个外部定义

对象的标识符可能有多个外部定义,有或没有明确使用关键字extern; 如果定义不一致,或者初始化了多个,则行为未定义(6.9.2).

但正式地说,在C和C++语言中,你有完全相同的多重定义错误.请求你的C编译器更迂腐(禁用扩展,如果它有一个选项),你的C编译器也会产生与你的C++编译器相同的错误.

同样,您的代码包含多个变量定义var,这在C和C++中都是错误的.你的#ifdef指令根本没有解决任何问题.Preperocessor指令在这里无法帮助你.预处理器在每个翻译单元中本地和独立地工作.它无法跨翻译单位看到.

如果要创建全局变量(即所有翻译单元共享的相同变量),则需要对该变量进行一个且仅一个定义

int var;
Run Code Online (Sandbox Code Playgroud)

在一个且只有一个翻译单元.所有其他翻译单位应接收非定义声明var

extern int var;
Run Code Online (Sandbox Code Playgroud)

后者通常放在头文件中.

如果您需要var在每个翻译单元中使用单独的自变量,只需在每个翻译单元中将其定义为

static int var;
Run Code Online (Sandbox Code Playgroud)

(尽管在C++中,这种用法static现在已被弃用并被无名空间名称取代).