是否可以强制(比如“gcc”)为C和C++中相同的源代码生成相同的二进制文件
Is it possible to force say, `gcc`, to produce identical binaries for identical pieces of source code in C and C++?
假设有一个C程序,如下所示:
int main(int argc, char** argv)
{
return 0;
}
我有两个以上源代码的文件,一个扩展名为"c",另一个扩展名称为"cpp"。我将它们分别编译为C和C++程序二进制文件不同。我认为C++是一种"零开销"语言?:-)我试图找到的是两种不同设置的编译器标志,其中生成的二进制文件是相同的。最好是某种语言标准,而不是任何类型的GCC扩展。
二进制文件不同
它们有何不同?
GCC将在文件中嵌入有关原始源文件名和所用选项的信息,因此对于不同的文件名,即使内容相同,也总是会有一些差异。
如果我将您的程序编译为C和C++,我看到的唯一区别是C++版本链接到libstdc++
,这在使用g++
进行链接时会自动发生。如果我使用gcc
来链接,那么二进制文件几乎是相同的。
注意:您可以使用gcc
编译C++程序,gcc
和g++
二进制文件只是查看文件名并调用正确的编译器二进制文件(cc1
用于C,cc1plus
用于C++)进行实际编译的驱动程序。看见http://gcc.gnu.org/onlinedocs/gcc/Invoking-G_002b_002b.html了解更多详细信息。
这表明,对于相同的源代码,汇编程序输出的唯一区别是给出原始文件名的字符串,而目标文件的大小相同:
$ cat f.c
cat: f.c: No such file or directory
$ rm f.c
$ cat > f.c
int main(int argc, char** argv)
{
return 0;
}
$ ln -s f.c f.cc
$ gcc f.c -S -o f.c.s
$ g++ f.cc -S -o f.cxx.s
$ diff f.c*.s
--- f.c.s 2012-08-26 13:45:58.109711329 +0100
+++ f.cxx.s 2012-08-26 13:46:00.482634256 +0100
@@ -1,4 +1,4 @@
- .file "f.c"
+ .file "f.cc"
.text
.globl main
.type main, @function
$ gcc f.c -c -o f.c.o
$ g++ f.cc -c -o f.cxx.o
$ ls -l f.c*.o
-rw-rw-r--. 1 jwakely users 1240 Aug 26 13:46 f.c.o
-rw-rw-r--. 1 jwakely users 1240 Aug 26 13:46 f.cxx.o
在最终的可执行文件中,差异来自于它的链接方式,无论C++标准库是否链接到:
$ gcc f.c.o -o a.c.out
$ gcc f.cxx.o -o a.cxx.out
$ g++ f.cxx.o -o a.cxx.libstdcxx.out
$ ls -l a.c*.out
-rwxrwxr-x. 1 jwakely users 6323 Aug 26 13:48 a.c.out
-rwxrwxr-x. 1 jwakely users 6468 Aug 26 13:48 a.cxx.libstdcxx.out
-rwxrwxr-x. 1 jwakely users 6324 Aug 26 13:48 a.cxx.out
如果您不需要C++标准库,请不要链接到它。
这只是"我的空main有多短"错误问题的另一个版本。
"基础设施"的一部分携带启动和结束代码,以及在任何情况下都必须链接的标准库全局对象,无论程序实际是什么
测量一个空的主程序,实际上就是测量启动/结束代码的大小。这在C和C++中肯定是不同的,因为C++要做的准备调用main的事情比C实际要做的多得多
我不知道你说的"零开销语言"是什么意思。C和C++都不是。它们都将各自域中的开销降至最低。根据定义,唯一的零开销语言是本机代码。
当然它们是不同的,即使是像函数名这样简单的东西,c和c++也会有不同的处理方式。c中的void foo()
就是c++中的foo
,因为c版本没有包含足够的信息来处理具有不同参数列表(如void foo(int)
)的多个foo函数,所以这个名称会被破坏。
然后有不同的标准库,它们在默认情况下被链接进来,因为它们被大多数c/c++程序使用(对于零开销声明,这可以被禁用)。
最重要的是关于定义良好的行为的不同规则,c++不是c的超集,虽然有大量的重叠,但在许多情况下它们是不同的。请参见c和c++中的示例sizeof('a')
。
结论:c和c++编译器在可能的情况下从相同的源代码中生成相同的二进制文件是极不可能发生的。
- 正在读取二进制文件(is_open)
- 在C++中将类(带有Vector成员)保存为二进制文件
- 如何从二进制文件中读取字符串
- 保存/加载大量短数组到二进制文件
- 从二进制文件中读取整数数组
- Android 在编译二进制文件时重建静态库
- 在 C++ 中将双精度变量写入二进制文件
- clang 的 libFuzzer 可以在同一二进制文件中测试超过 1 个 API 吗?
- C++:实际上不是从二进制文件中读取
- 如何从二进制文件中的给定符号中获取调用程序图
- 将内部带有矢量的结构保存/读取到二进制文件中
- 编译多个C++文件.调用二进制文件以运行代码
- 如何使用位字段将数据从二进制文件复制到结构中?
- uint8_t同一二进制文件的不同十进制值
- C++单个生成文件多个二进制文件
- 尝试将数字写入二进制文件时引发异常
- C++中读/写二进制文件
- 如何忽略某些二进制文件的执行?
- 对在不同二进制文件中创建的对象文件的依赖关系
- 我的 SDL2 程序需要哪些二进制文件,以便它在另一台未安装 SDL2 的计算机中工作