是否有任何情况下有效的 C 代码无法使用 g++ 正确编译 [重复]

Posted

技术标签:

【中文标题】是否有任何情况下有效的 C 代码无法使用 g++ 正确编译 [重复]【英文标题】:is there any circumstance under which valid C code will not compile properly using g++ [duplicate] 【发布时间】:2012-07-26 18:24:51 【问题描述】:

可能重复:“C subset of C++” -> Where not ? examples?

我知道 C 是 C++ 的子集(即不存在不是有效 C++ 代码的有效 C 代码)。我的问题是g++ 是否与所有 C 代码完全兼容。例如,会

g++ -o testing test.c

生成与

相同的二进制文件
gcc -o testing test.c

在所有情况下?

更具体地说,如果它们并不总是创建相同的二进制文件,是否有任何理由会出现问题?如果我不确定代码,总是使用g++ 是否安全?

【问题讨论】:

there does not exist valid C code that is not valid C++ code - 错了。看看 VLA。 C++ 确实有 C 代码可能用作变量名的关键字。 见:en.wikipedia.org/wiki/Compatibility_of_C_and_C%2B%2B 我的“关闭:问题的前提是错误的”在哪里? @ewok: 另请注意,如果您的 C 头文件未准备好从 C++ 中包含,您还会遇到链接器错误(C++ 编译器会破坏名称,而 C 库不会,符号赢了不匹配)。这超出了是否所有 C 代码都可以在 C++ 编译器中编译 【参考方案1】:

C 不是 C++ 的子集。

试试:

foo.c

int main() 
    int class = 0;
    return 0;

在这里玩得开心:Where is C not a subset of C++?

【讨论】:

您应该投票以关闭为完全重复(或在问题中添加评论),而不是提供基本上是链接的答案 我标记为确切的重复,因为我没有代表要关闭,除了发布这个答案。【参考方案2】:

很难弄清楚如何回答这个问题:

C 不是 C++ 的完整子集。 C 中有几件事不是有效的 C++。可变长度数组就是这样一种东西。来自void* 的隐式转换是另一个。 g++ 将接受什么代码取决于传递给它的标志。它是通过调用g++(哪个版本?)还是使用-ansi 编译的? -pedantic? std=<lang> 怎么样? 最后,代码是否被接受与“它是否产生相同的二进制文件”是完全不同的问题。两个编译器都接受的代码可能会生成执行相同操作但仍不相同的二进制文件相同

考虑到所有这些模棱两可的情况,我们不可能给你一个明确的答案。

【讨论】:

【参考方案3】:

C 不是 C++ 的子集。从来没有。 C99 与 C++ 有显着差异,但即使是经典的 C89/90 也不是 C++ 的子集,存在大量显着差异。

即使对于 C89/90,在 C++ 编译器下“破坏”有效 C 代码的差异也将包括

    C++ 中更严格的隐式指针类型转换 嵌套结构声明在 C++ 中为类范围,在 C 中为文件范围 运算符语法(以及由此产生的运算符优先级)在语言之间略有不同 暂定定义在 C++ 中是非法的 新关键字,C++ 中没有隐式 int 规则... 等等等等

【讨论】:

说在*.c 文件上调用g++ 将自动调用C 编译器是错误的。我刚刚自己和this is the output 测试了这个(注意调用cc1plus,C++ 后端编译器)。拨打gcc 时使用文件扩展名。不同之处在于,使用 C++ 编译器编译 C 源文件将默认生成异常处理信息和类型信息,否则这些信息会丢失。 gcc -x c C 编译器有一些选项,例如 -fexceptions,它们强制此信息用于 C 编译。 @rubenvb:我的立场是正确的。谢谢。我认为这种行为也延伸到g++

以上是关于是否有任何情况下有效的 C 代码无法使用 g++ 正确编译 [重复]的主要内容,如果未能解决你的问题,请参考以下文章

无法弄清楚为什么我的部分复制命令有效,有些则不然

C 和 C++ 编码标准

在这种情况下,如何正确检查用户输入是否为Integer?

如何在不使用java发送任何邮件的情况下检查域中是不是存在电子邮件ID

是否有任何代码可以在不裁剪和放大android的情况下设置壁纸?

如何在VSCode内编译运行C++