GCC 使用摘记

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 这种表达。支持 typedettypename=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++ 编译。

你可能感兴趣的:(GCC 使用摘记)