gcc 与 g++ 的区别

gcc 和 g++

  • GCC:GNU Compiler Collection(GUN 编译器集合);

  • g++ 是 GCC 中的 GUN C++ Compiler(C++编译器)。

在已编译好的 C 或者 C++ 代码的前提下,GCC 编译器已提供了调用接口,可以通过执行 gcc 或者 g++ 指令来调用 GCC 编译器,两者都可以编译 C 或者 C++ 语言程序,但这不是两者的区别。

实际上只要是 GCC 支持编译的程序代码,都可以使用 gcc 命令完成编译,可以说 gcc 是 GCC 编译器的通用编译指令,因为 gcc 指令根据程序文件的后缀名可以执行判断出当前程序所用编程语言的类别:

  • xxx.c:默认以编译 C 语言程序的方式编译此文件;

  • xxx.cpp:默认以编译 C++ 语言程序的方式编译此文件;

  • xxx.m:默认以编译 Objective-C 语言程序的方式编译此文件;

  • xxx.go:默认以编译 Go 语言程序的方式编译此文件;

  1. gcc 指令对 .c 文件则以 C 语言代码对待,对 .cpp 文件则以 C++ 代码对待;

  2. g++ 指令对.c 或者 .cpp 文件则都以 C++ 代码对待;

  3. gcc 指令编译执行 C++ 程序,需要添加命令使得链接必要的 C++ 标准库:

[root@bogon ~]# gcc -xc++ demo.cpp -lstdc++ -shared-libgcc

  1. 使用g++编译文件时,g++会自动链接标准库STL,而gcc不会自动链接STL

命名倾轧(函数重载及原理)

函数重载

C 语言中一个函数不能与另一个函数重名;C++ 中只要函数的参数列表与另一函数的参数列表不完全相同,函数名就可以相同。

重载原则

  1. 函数名相同,函数参数列表不同(类型、个数、顺序);
  2. 匹配原则1:严格匹配,找到再调用;
  3. 匹配原则2:通过隐式类型转换寻求一个匹配,找到再调用;
  4. 返回值类型不构成重载条件。

重载实现原理

利用 name mangling(倾轧)技术对函数名进行更改,区分参数不同的同名函数。

  • ​编译器通过函数名和参数类型识别重载函数。为了保证类型安全的连接(type-safe linkage),编译器用参数个数和参数类型对每一个函数标识符进行专门编码(名字改编:name mangling 或者 名字修饰:name decoration)。

  • ​类型安全的连接使得程序能够调用合适的重载函数并保证了参数传递的一致性,编译器能够检查到并报告连接错误。

查看符号表

  1. nm 目标文件;
  2. objdump -t 目标文件;
  3. readelf -s 目标文件
  4. strings 目标文件

GCC 自动识别的文件扩展名

文件名 + 扩展名GCC 编译器识别的类型
file.c尚未经过预处理的C 源程序文件
file.j经过预处理操作,但未进行编译、汇编和连接的 C 源代码文件
file.cpp
file.cp
file.cc
file.cxx
file.CPP
file.c++
file.C
尚未经过预处理操作的 C++ 源代码文件
file.ii经过预处理操作,但未进行编译、汇编和连接的 C++ 源代码文件
file.s经过编译生成的汇编代码文件
file.hC、C++或者 Objective-C++ 语言头文件
file.h
hfile.H
file.hp
file.hxx
file.hpp
file.HPP
file.h++
file.tcc
C++ 头文件

命名反倾轧

c++filt _Z4funci

查看反倾轧的符号表

nm -C 目标文件
objdump -t -C 目标文件

禁用命名倾轧

C++ 命名倾轧的函数无法被 C 调用。C++ 函数必须是没有倾轧的才能调用。

使用声明 extern "C" 禁止命名倾轧:

#ifndef __CPP_H_
#define __CPP_H_

#ifdef __cplusplus
extern "C" {
#endif // __cplusplus

int fun(int n);

#ifdef __cplusplus
}
#endif // __cplusplus

#endif // __CPP_H_

编译

函数声明编译器编译函数符号查找函数符号
void func(int)g++_Z4funci_Z4funci
void func(int)gccfuncfunc
extern "C" void func(int)g++funcfunc
extern "C" void func(int)gcc错误
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
gcc和g之间的区别在于它们在编译和链接过程中的行为略有不同。gcc是GNU Compiler Collection的缩写,是一个包含多个编译器的工具集合。而g只是gcc命令的一个别名。 在编译阶段,gcc和g都会调用gcc编译器来处理C语言或C++代码,并生成目标文件。对于C语言代码来说,gcc和g是等价的。然而,由于gcc命令不能自动链接使用的库,所以通常使用g命令进行链接。为了统一起见,通常将编译和链接过程都使用g命令来完成。 另外,有一些关于gcc和g的误解需要澄清。首先,extern "C"与gcc或g没有直接的关系。extern "C"是C++编程中的一个关键词,用于指定使用C风格的函数命名和链接规则。其次,gcc和g在定义__cplusplus宏方面也有所不同。gcc不会定义__cplusplus宏,而g会定义该宏,这是因为g是gcc命令的别名,用于编译C++代码时,g会自动添加-C选项来定义__cplusplus宏。 综上所述,gcc和g之间的区别主要在于对编译和链接过程的处理方式略有差异,而不在于语言本身或特定的编译选项。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [GccG++区别(通俗易懂)](https://blog.csdn.net/weixin_47156401/article/details/125653897)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *2* *3* [gccg++区别](https://blog.csdn.net/u013457167/article/details/80222557)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值