GCC 使用摘记

发布: 2009-09-08 17:00


1. 几个子程序和说明




























cc1 C 的实际编译程序
cc1plus C++ 的实际编译程序
collect2 在不使用 GNU 连接程序的系统上,用来产生特定的全局初始化代码
crt0.o 为每个系统定制的初始化和结束代码
libgcc 默认连接的 gcc 例程库
libstdc++ 默认连接的 g++ 例程库





2. 几个重要的和 GCC 协同工作的程序,主要来自 binutils 包。
































































addr2line 将文件中的调试信息翻译成为源文件的对应行号
ar 用于维护目标代码的 archive,也就是创建库的程序
as GNU 的汇编器
c++filt 用于完成 C++ 和 Java 的 mangling/demangling
gcov gprof 的配置工具
gprof 报告各个函数的执行时间
ld GNU 的连接程序
nm 列出目标文件中定义的符号
objcopy 完成目标代码的复制和翻译
objdump 显示目标文件的各种信息,包括代码的反汇编结果
ranlib 创建和添加 ar 创建的库文件的索引
readelf 获取 elf 文件信息
size 列出目标文件中每部分的尺寸
strings 从目标文件中析取可显示的字符串
strip 从目标文件/库中去掉符号表以及其它调试使用的信息





3. 预处理程序,最常见的 C 使用的预处理命令,如 #define 和 #undef,

#if #elif #else #endif,#ifdef 和 #ifndef,#include,##(连接字符) 就不多说了。

#error 会引起 cpp 的中断,而 #warning 仅仅给出警告而不中断。

#pragma 主要是用于定义编译器相关的一些命令,GCC 中可用的有

#pragma GCC dependency "file" warning information

定义了该文件对 file 的时间戳依赖关系,即如 file 较当前文件新则发出警告。

#pragma GCC poison function-name

如果使用了 function-name 则发出警告。与 #pragma 等价的有 _Pragma("")

表达,这是为了在 macro 内部也能使用该功能引入的。



4. 预定义的宏




















































































__NASE_FILE__ 源文件的完整路径名,和 __FILE__ 不同,被引用的文件仍然是原来文件名
__CHAR_UNSIGNED__ 用于指定该机器上 char 是无符号类型
__cplusplus 使用 C++ 编译器编译
__DATE__ 编译时的日期
__FILE__ 编译文件名
__func__ 同 __FUNCTION__
__GNUC__ GCC 的主版本号
__GNUC_MINOR__ GCC 的次版本号
__GNUC_PATCHLEVEL__ GCC 的修订号
__GNUG__ 由 C++ 编译程序定义
__INCLUDE_LEVEL__ 指 #include 的层次
__LINE__ 当前行号
__NO_INLINE__ 不允许 inline
__OPTIMIZE__ 打开了优化选项
__OPTIMIZE_SIZE__ 打开了对编译出文件尺寸的优化
__STDC__ 表示该程序符合 ansi C 标准
__STDC_HOSTED__ 表示宿主具有标准 C 的环境
__STDC_VERSION__ 标准 C 制定时间
__TIME__ 编译时系统时间
__VERSION__ GCC 版本号





5. 在 iso646.h 中为操作符定义了 C++ 对应的操作符名称,如 and,or 等



6.产生依赖关系列表,gcc -E -M src



7. GCC 对 C 的扩展主要有,__alignof__( typename ) 返回对齐信息,可以

使用参数变长数组(在函数里面定义),同时还可以把该数组作为参数传递,

void f( int length, char buf[length] )

如果需要倒着写,需要前向声明,用分号隔开

void f( int length; char buf[length], int length )

允许结构体最后一个成员为 0 长度数组,这样可以创建变长数组。



通过 __attribute__ 可以给函数增加额外的信息便于优化,如 ((noreturn))

表明没有返回值,又如 pure 表明不会修改全局变量,noinline 表示不会 inline,

align(n) 表示执行对齐,weak,alias 连用表示是别名,always_inline 表示

总会 inline,const 不访问全局内存便于优化,constructor 是比 main 更早调用

的函数,destructor 是在 exit() 之后调用的,deprecated 表示过时了编译时发出

警告,format( style, str-pos, var-pos ) 要求编译器检查是否为 style(如 printf 和 scanf)

的函数,str-pos 是字符串参数的位置,var-pos 是可变长度参数列表的开始位置。

类似的还有 format_arg。malloc 告诉编译器其返回指针和 malloc 一样对待,

no_intrument_function 不会进行 profiling,section("sec-name") 将代码放入指定段。



类似的一些可以修饰变量,另有 mode(指定为 byte、word 或者 pointer),nocommon

(不会作为公共变量),packed(没有间隙),vector_size,类似数组。



复合语句 {} 可以返回值,用 () 包裹之,但不适用于 C++。y? y : z 可简写为 y? : z。

可以对 enum 进行声明但不定义



另有底层的三个函数,__builtin_apply_args(),__builtin_apply() 和 __builtin_return()

可以把当前函数的参数直接传递给后面的函数。

而 __builtin_return_address() 返回 ret 时应跳转的地址(frame 中第一个记录的 %ebp)

__builtin_frame_address( int ) 返回第几层的 frame 起始地址。



允许函数嵌套定义,并且该函数地址可以传递。支持 $ 命名变量名,goto 的 label 可以用

&& 取址并赋值给变量进行 goto。__label__ 可以声明局部标识为 goto 使用。只要左值表

达式产生左值(地址)即可。



可变参数宏,c99 标准为使用 ... 和 __VA_ARGS__。



在 switch 中支持 case 1 ... 9 这种表达。支持 typedet typename=var,从而将某变量的类

型定义为需要的类型。typeof(var) 产生 var 的类型。



8. C++ 里面另有 __PRETTY_FUNCTION__,而 #progma interface 和 #pragma implementation

可以表示类的性质,另有 >? 和 <? 表示返回较大较小的,并可以重载。C99 中 restruct 关键字

可以用 __restrict__。



9. C++ 中调用 C 程序只需要 external "C" 声明即可。而 C 中调用 C++ 函数也是用 external "c"

声明函数并用 g++ 编译。



原文: http://qtchina.tk/?q=node/333

Powered by zexport