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

标签 c++ c gcc compiler-errors g++

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

文件main.c

#ifndef VAR
#define VAR
int var;
#endif
int main(){}

文件其他.c

#ifndef VAR
#define VAR
int var;
#endif

用gcc编译

gcc main.c other.c
>> success

用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

我的 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.

最佳答案

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

J.5 Common extensions

The following extensions are widely used in many systems, but are not portable to all implementations. [...]

J.5.11 Multiple external definitions

There may be more than one external definition for the identifier of an object, with or without the explicit use of the keyword extern; if the definitions disagree, or more than one is initialized, the behavior is undefined (6.9.2).

但形式上,您在 C 和 C++ 语言中都存在完全相同的多重定义错误。要求你的 C 编译器表现得更迂腐(禁用扩展,如果它有一个选项),你的 C 编译器也会生成与你的 C++ 编译器完全相同的错误。

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

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

int var;

在一个且只有一个翻译单元中。所有其他翻译单元应接收 var

的非定义声明
extern int var;

后者通常放在头文件中。

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

static int var;

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

关于c++ - 在 c++ 中编译但在 c (gcc) 中编译时很复杂,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11874494/

相关文章:

c++ - Qt:在 Mac OS X 上更改应用程序 QMenuBar 内容

c++ - 零大小数组分配是什么/意味着什么?

c - 当使用导致无限循环的无符号整数时,在 For 循环条件中向后迭代数组以在 0 处停止

c - 函数指针混淆

c++ - Blob 内数据的对齐和填充

c++ - Crypto++/iOS 64 位项目中的 undefined symbol

c - ((double *)0) 在 C 内部做什么

c++ - 小 N 的 std::map 与 unordered_map 内存占用

c++ - 从整型常量表达式转换为空指针

c++ - 这个 union 会打破严格的别名吗?浮点寄存器呢