【发布时间】:2018-01-06 10:09:36
【问题描述】:
我在一个移植到 C++ 的 C 项目中遇到了以下构造;
enum TestEnum
{
A=303,
B=808
} _TestEnum;
int foo()
{
_TestEnum = B;
}
当使用 GCC 编译并查看生成的代码时,我得到:
nils@doofnase ~ $ gcc -std=c90 -O2 -c ./test.c -o test.o
nils@doofnase ~ $ size test.o
text data bss dec hex filename
59 0 0 59 3b test.o
因此使用了零字节的数据或 BSS 段。
另一方面,如果我用 C++ 编译,我会得到:
nils@doofnase ~ $ g++ -std=c++11 -O2 -c ./test.c -o test.o
nils@doofnase ~ $ size test.o
text data bss dec hex filename
59 0 4 63 3f test.o
我看到在 BSS 中分配了四个字节的存储空间,正如我所期望的那样。
此外,在 C 项目中,枚举定义实际上位于一个头文件中,该头文件包含在多个 c 文件中。该项目编译和链接就好了。当编译和链接为 C++ 时,编译器会抱怨 _TestEnum 是在多个对象中定义的(没错!)。
这里发生了什么?我在看一些古老的 C 语言特例吗?
编辑:为了完整起见,这是 gcc 版本:
nils@doofnase ~ $ gcc --version
gcc (Ubuntu 5.4.0-6ubuntu1~16.04.5) 5.4.0 20160609
【问题讨论】:
-
With
-O2我希望编译器在 C 和 C++ 中都内联foo()的代码;) 此外,您应该在 C 和 C++ 中收到foo()的警告返回类型int并且不返回值。也许代码 sn-p 太小而无法知道应该发生什么......因为它很可能取决于代码的其余部分。 -
是的,请修复代码,并添加
-Wall -
请注意,与正则表达式
^_[A-Z]匹配的标识符(如您的_TestEnum)在 C 和 C++ 中都保留,并且引入它们会导致未定义的行为(有关详细信息,请参阅 this post)。