CC, gcc and g++之间的区别是什么?

9 浏览
0 Comments

CC, gcc and g++之间的区别是什么?

在生成汇编代码、可用库、语言特性等方面,编译器CC、gcc和g++在编译C和C++代码时有哪些区别?

0
0 Comments

CC、gcc和g++之间的区别是什么?

CC是一个环境变量,指向系统的C编译器。它指向的内容(可访问的库等)取决于平台。通常它指向实际的C编译器(驱动程序)/usr/bin/cc。在Linux平台上,CC几乎总是指向/usr/bin/gcc。

gcc是GNU编译器集合的驱动程序二进制文件。它可以编译C、C++和可能其他语言;它通过文件扩展名确定语言。

g++是一个类似于gcc的驱动程序二进制文件,但为编译C++设置了一些特殊选项。值得注意的是(根据我的经验),g++默认会链接libstdc++,而gcc不会。

“驱动程序二进制文件”是什么意思?

大多数C编译器(特别是GCC)有许多执行编译工作的程序。有一个顶级程序,称为“gcc”,它是编译器驱动程序;它解析众多命令行选项,并协调编译器的其他阶段——解析器/分析器、优化器、汇编器和链接器,通常(除非您仅请求预处理,否则预处理器通常不是单独的阶段)。尽管它本身不会触及C源文件,但它(编译器驱动程序)是一个相当复杂的程序。

CC也是Sun C++编译器的名称,而不是一个环境变量。

SGI的C++编译器也是CC。

我想Managu是在考虑"./configure + make"可以使用名为CC的环境变量来影响所使用的C编译器,但通常情况下没有名为CC的环境变量。

CC也是Sun Solaris CPP编译器的名称。

在搜索cc作为环境变量时,我遇到了与帖子"getenv("cc") is returning NULL, why?"中提到的相同问题。在帖子"getenv("cc") is returning NULL, why?"中,用户"aschepler"、"john.jansen"和"gsamaras"似乎都表明cc不是一个环境变量。当我使用"env >> env_vars.txt"来读取环境变量(在Linux中),"cc"和"CC"都没有出现作为环境变量。

0
0 Comments

CC、gcc和g++之间的区别是平台特定的。在Linux上的情况与Solaris上的情况不同。简单的区别是'gcc'和'g++'的区分:

- gcc是来自GCC(GNU编译器集合)的GNU C编译器。

- g++是来自GCC的GNU C++编译器。

而'CC'(和'cc')的含义则因平台而异:

- 在Solaris上,CC通常是Sun C++编译器的名称。

- 在Solaris上,cc通常是Sun C编译器的名称。

- 在Linux上,如果存在,CC可能是g++的链接。

- 在Linux上,cc是gcc的链接。

然而,即使在Solaris上,cc可能是位于/usr/ucb的旧的基于BSD的C编译器。实际上,通常不会安装这个编译器,只会有一个失败的存根,给那些尝试编译和安装自配置软件带来混乱。

在HP-UX上,默认的'cc'仍然是一个仅支持K&R C的编译器,用于必要时重新链接内核,对于现代软件开发来说不可用,因为它不支持标准C。您必须使用替代的编译器名称(如'acc')。类似地,在AIX上,系统C编译器的名称为'xlc'或'xlc32'。

经典上,系统默认的编译器称为'cc',当自配置软件不知道使用什么编译器时,会回退到该名称。

POSIX试图通过要求存在c89(最初)和后来的c99程序来解决这个问题;这些编译器与ISO/IEC 9899:1989和9899:1999 C标准兼容。值得怀疑的是,POSIX是否成功。

该问题询问的是特性和库方面的区别。与之前一样,答案在某种程度上是平台特定的,部分是通用的。

最大的区别在于C编译器和C++编译器之间。C++编译器可以接受C++程序,但不能编译任意的C程序(尽管可以编写C的子集,也可以被C++理解,但许多C程序不是有效的C++程序)。同样,C编译器可以接受C程序,但会拒绝大多数C++程序(因为大多数C++程序使用C中不可用的结构)。

可用于使用的库集取决于语言。C++程序通常可以在特定平台上使用C库;C程序通常不能使用C++库。因此,C++有更多可用的库集。

请注意,如果您在Solaris上,CC生成的目标代码与g++生成的目标代码不兼容,它们是两个独立的编译器,具有不同的异常处理和名称修饰约定(名称修饰是故意不同的,以确保不兼容的目标文件不会链接在一起!)。这意味着如果您想使用使用CC编译的库,您必须将整个程序都使用CC进行编译。这还意味着如果您想使用使用CC编译的一个库和使用g++编译的另一个库,您将无法成功。您至少需要重新编译其中一个库。

就生成的汇编代码质量而言,GCC(GNU编译器集合)的工作非常出色。但有时本地编译器效果更好。我相信Intel编译器具有尚未在GCC中复制的更广泛的优化功能。但在不知道您关注的平台时,这些推测都是有风险的。

就语言特性而言,编译器通常都与当前标准(C++98、C++2003、C99)很接近,但标准语言和编译器支持的语言之间通常存在一些小差异。旧的C89标准支持对所有C编译器来说基本相同(且完整)。在语言的较阴暗的角落存在差异。您需要理解'undefined behaviour'、'system defined behaviour'和'unspecified behaviour';如果调用未定义行为,您将在不同的时间获得不同的结果。编译器还有许多选项(特别是GCC)可以调整其行为。GCC具有各种扩展,如果您知道只针对该编译器系列,则可以简化生活。

在OSX(至少是Sierra 10.2)上,它是指向clang的符号链接。

对于Debian buster,我刚刚运行了readlink -f $(which cc) $(which gcc) /usr/bin/x86_64-linux-gnu-gcc-8 /usr/bin/x86_64-linux-gnu-gcc-8命令。我只运行了ls -la /usr/bin | grep cc,没有找到'-> clang'。为什么您认为它是指向clang的符号链接?

- 在某个时间,gcc是指向clang的链接(Sierra 10.12现在相当老了,2018年发布,不应该再使用)。现在编译器不一定再链接了;规则已经改变了(多次)。在我的Monterey 12.6.3机器上,/usr/bin/gcc/usr/bin/clang都是指向相同可执行文件的76个硬链接之一(其他名称包括gitm4indentswiftar等)。macOS上的规则经常更改。

- 为了确保我理解您的“措辞”正确。您是说在/usr/bin中有76个可执行文件吗?这76个可执行文件中有两个是clanggcc?好的,到目前为止我明白了。您的措辞中唯一不理解的部分是,“指向相同可执行文件的硬链接”。您的意思是:“尽管gccclang不再是符号链接,并且指向不同的内容,但它们是同一个可执行文件的硬链接。”那么“相同”的意思是什么?

- 我的意思是,在/usr/bin中有76个具有相同inode号的文件。例如:1152921500312781232 -rwxr-xr-x 76 root wheel 167120 Jan 11 00:03 gcc1152921500312781232 -rwxr-xr-x 76 root wheel 167120 Jan 11 00:03 clang以及其他74个文件。是的,我得到了一个19位的inode号。显然,这些都是看名字被调用并运行在其他地方安装的程序,主要是在/Library/Developer/CommandLineTools/usr/bin中的可执行文件。这些文件大小是不同的,因为它们执行不同的任务。

- 您的意思是这76个项目都是使用/Library/Developer/CommandLineTools/usr/bin进行调用的吗?我理解调用的工作原理,第一个参数用于指定内容。就像这就是swiftcswift之间的区别。但是使用相同的二进制文件来处理gitarindent以及swiftclanggcc似乎太多了。我了解发生了什么,但不理解其原因/设计。您能否指点我一些信息?

- 不;在/usr/bin中有一个控制程序,有76个不同的名称。该控制程序根据其被调用的方式运行/Library/.../bin目录中隐藏的相应命令。作为用户,我键入(或者我的make程序运行)gcc,那就是/usr/bin/gcc,但是该程序与/usr/bin/swiftc和所有其他程序是同一个物理程序,但是它会运行/Local/.../bin/gcc。我不完全清楚苹果为什么这样做。这样做可以更轻松地监视正在使用的内容-有时我会想知道是否会因此而延迟(但可能不会)。

- 只是为了好玩,我运行了ln -s /usr/bin/gcc ozymandias; ./ozymandias --version命令。它报告“xcode-select: Failed to locate 'ozymandias', requesting installation of command line developer tools.”然后弹出一个窗口询问是否安装命令行工具。 xcode-select是一个独立的可执行文件-不同的inode号、大小,并且只有一个链接。(Ozymandias是Percy Bysshe Shelley的一首诗的名称-“我伟大的作品,威严的人们,请瞻仰并绝望。除此之外,再无其他。在那巨大的残骸的周围,无边无际的沙漠地带伸展开来,孤独而平坦的沙滩一直延伸到远方。”)

0
0 Comments

在Linux中,cc与gcc有关联。为了检查它,我们可以使用以下命令:

whereis cc

输出结果可能如下:

cc: /usr/bin/cc /usr/include/cc /usr/share/man/man1/cc.1.gz

同样的情况也适用于c++:

whereis c++

输出结果可能如下:

c++: /usr/bin/c++ /usr/include/c++ /usr/share/man/man1/c++.1.gz

通过以下命令查看c++的符号链接:

ls -l /usr/bin/c++

输出结果可能如下:

lrwxrwxrwx 1 root root 21 Jul 31 14:00 /usr/bin/c++ -> /etc/alternatives/c++

再次使用命令查看符号链接:

ls -l /etc/alternatives/c++

输出结果可能如下:

lrwxrwxrwx 1 root root 12 Jul 31 14:00 /etc/alternatives/c++ -> /usr/bin/g++

从上面的输出可以看出,cc实际上是链接到gcc的,而c++则是链接到g++的。因此,cc和gcc可以互换使用,c++和g++也可以互换使用。

这种关联关系的原因是为了方便用户使用不同的编译器。cc和gcc都可以用于编译C语言代码,而c++和g++则可以用于编译C++代码。这样做的好处是,用户可以根据自己的需求选择不同的编译器,而不必担心代码是否能够正常编译。

如果用户想要使用cc编译C++代码,可以使用以下命令:

cc -x c++ filename.cpp

同样地,如果用户想要使用c++编译C代码,可以使用以下命令:

c++ -x c filename.c

通过这种方式,用户可以根据自己的需要选择合适的编译器来编译代码。这种灵活性使得在不同的情况下选择合适的编译器变得更加容易。

0