基本介绍:
GCC 的意思是 GNU C Compiler 。经过了这么多年的发展,GCC 已经不仅仅能支持 C 语言。它现在还支持 Ada 语言、C++ 语言、Java 语言、Objective C 语言、Pascal 语言、COBOL语言,以及支持函数式编程和逻辑编程的 Mercury 语言等。所以GCC 也不再单只是 GNU C 语言编译器的意思了,而是变成了 GNU Compiler Collection 也即是 GNU 编译器家族的意思了。
相关问题:
gcc 的处理步骤包括: 预处理, 编译,汇编,链接。gcc 实际可以作为一个链接器使用,那么他和专用的链接器 ld 相比差别在哪里? ld 工作的时候可以通过一个链接脚本有更加丰富的功能
相关选项的介绍:
gcc 也包括g++ 的一些option的介绍,
gcc 连接库的搜索方法
-L 指定库的路径,和路径之间无空格, 多个-L的顺序决定了gcc进行搜索的顺序
-l 指定库的名称,和名称之间无空格, libpthread 的使用是 -lpthread,需要去除 lib前缀
使用g++ 进行目标文件的链接的实例如下:
g++ test.o -L./ -llog -L/usr/local/lib -lboost_thread -o test.out
上面的命令不能指定是进行动态链接还是进行静态链接,会优先进行动态链接。
-o 指定输出目标名称,缺省的时候, gcc 编译出来的文件是a.out。
gcc 用到的环境变量
环境变量 LD_LIBRARY_PATH 指明程序在运行时动态库的搜索路径,动态库是运行时加载所以需要搜索。
临时修改环境变量 LD_LIBRARY_PATH 的方法如下:
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/lib
环境变量LIBRARY_PATH 指明静态库的搜索路径。
echo $(LIBRARY_PATH) 可以检测当前的搜索路径。
gcc 中命令行定义宏的选项
-Dmacro 相当于C语言中的#define macro
-Dmacro=defn 相当于C语言中的#define macro=defn
-Umacro 相当于C语言中的#undef macro
gcc 中头文件查找路径的选项
-Idir 在你是用#include”header.h”的时候,gcc/g++会先在当前目录查找头文件,如果没有找到,他回到缺省的头文件目录找,
如果使用-I 指定了目录,gcc先在指定的目录查找,然后再按常规的顺序去找。
asm 扩展
GCC 添加了很多的语言特性,这些特性在ISO标准C中是没有的,如果想采用条件编译的方式进行区分,GCC总是定义了宏__GNUC__,它可以作为一个区分的标志。GCC 的asm的使用举例 : asm volatile("" ::: "memory"); asm extension 使得在C 语言的代码中可以进行嵌入汇编语言的代码,上面的这个例子中所使用的汇编语言是ARM汇编。一般来说使用asm扩展,可能会有以下的作用:
1. 可以用来提高程序的运行效率, 但是一般情况下这不是会增加compiler的负担吗?除非是asm中所采用的汇编指令compiler并不知晓。
2.阻止C 编译器对代码所进行的优化, 上面的例子中就是在compile level 实现memory barrier 的功能,阻止compiler所进行的指令重排。
asm扩展在什么情况下才是必需的? 如果没有必须使用asm扩展的情况,那么在GCC中增加这个功能是否多余?
匿名结构体和联合体的访问方式
在ISO C11标准中允许如下的使用方式,GCC 中同样也是允许的,例子代码:
struct {
int a;
union {
int b;
float c;
};
int d;
} foo;
foo.b的访问方式是允许的,但是匿名union中的成员: b, c 不能够和struct中的成员比如: a, d 重名。在非ISO C11标准的其他compiler应该是不允许这种访问方式。
查询变量和类型的对齐方式
GCC支持对类型和变量的对齐方式进行查询,这是标准C中没用的,是GCC的一个扩展。关键字是__alignof__,__alignof__(double) 在大多数的体系结构上会返回8,也就是8字节对齐。
struct foo { int x; char y; } foo1;
__alignof__(foo1.y)查询是没有意义的,因为按照结构体的填充方式 y 应该是4字节对齐的,但是这个查询却没有这个功能,它只能告诉你在这个体系结构上面char 类型是怎么对齐的,别无其他。
Zero Length Aarray
struct line {
int length;
char contents[0];
};
struct line* malloc_test(int this_length)
{
struct line *thisline = (struct line *)malloc (sizeof (struct line) + this_length);
thisline->length = this_length;
return thisline;
}
GCC 支持长度为0的数组,该种方式在ISO C90标准中是不支持的,上面的使用方式使得可以申请任意长度的数组。这种实现方法比下面的方法:
struct line {
int length;
char *contents;
};
更加优雅,使用的空间更少。使用该种方式需要malloc 两次,两次malloc 的空间几乎不可能正好是连续的。除此之外长度为0的数组的还有更重要的用途:
Non-Constant Initializers
GCC 支持由非常数进行数组的初始化, 这在ISO C99标准、C++标准中也是支持的。用法的举例如下:
foo (float f, float g)
{
float beat_freqs[2] = { f-g, f+g };
/* ... */
}
-W 选项
-Werror : 将产生的所有的警告都当做错误进行处理
-Werror= : 将指定的警告作为错误进行处理, -Werror=switch将告警-Wswitch作为错误进行处理
-Wimplicit : 告知GCC对隐式的声明进行告警。
参考资料
gdb 的相关资料
http://dirac.org/linux/gdb/04-Breakpoints_And_Watchpoints.php点击打开链接
https://gcc.gnu.org/onlinedocs/gcc-4.7.4/gcc/Extended-Asm.html点击打开链接
https://gcc.gnu.org/onlinedocs/gcc-4.7.4/gcc/Unnamed-Fields.html#Unnamed-Fields点击打开链接
http://stackoverflow.com/questions/295027/array-of-zero-length点击打开链接
https://gcc.gnu.org/onlinedocs/gcc-4.7.4/gcc/Zero-Length.html#Zero-Length点击打开链接
https://gcc.gnu.org/onlinedocs/gcc-4.7.4/gcc/Initializers.html#Initializers点击打开链接