gcc -Wall hello.c -o hello
gcc -v -Wall hello.c -o hello
gcc -Wall -c main.c hello.c
gcc main.o hello.o -o hello.c
gcc -Wall -lm hello.c -o hello
gcc -Wall -I(include) -L(目录没有空格) hello.c -o hello
创建(static)库文件:
ar cr libNAME.a file.o file1.o ...
ar -t libNAME.a(查看libNAME.a是由哪些构成的)
-ansi
按照ansi标准
gcc -Wall -ansi hello.c -o hello
严格按照ansi标准
gcc -Wall -ansi -pedantic hello.c -o hello
或者
-std=c89
-std=iso9899:199409
-std=c99
-Wall包含
-Wcommet 检测注释是否嵌套(c里不能嵌套,如果想注释,可以用#if 0 ..... #endif)
-Wformat 检测printf,sacnf里的输入输出格式与参数是否匹配
-Wunsed 检测时候有未使用的变量
-Wimplicit 检测未声明的函数(any function that are used without being declared)
-Wreturn-type 检测函数没有返回值,但是没有把函数声明为void类型
可以在man gcc里查看 -Wall的所有选项.
-D就是预定义里的define
也可以用-DNAME = VALUE,默认情况下-DNAME=1
gcc -Wall -DNUM="1+3" hello.c -o dd
gcc -E 只进行预处理(对理解一些特别复杂的宏特别有用)
gcc -E test.c
cpp -dM /dev/null 查看gcc所有定义好的宏
gcc -Wall -c -save-temps hello.c 保存中间生成的文件
-g 包含debug的信息
ulimit -c 查看允许的尺寸。
可以用umlimit -c unlimit 可以允许产生core文件
gcc -Wall -g hello.c
gdb a.out core.***
可以查看哪里出的错误
print p
backtrapce
gcc的优化:
在源码层次的优化: 仅仅是对源码的优化,不需要对机器指令的了解,与底层的处理器无关(CSE(保存一些中间结果来减少计算次数),FL(变为inline函数))
在机器码层次的优化
speed-space tradeoffs:需要速度和空间的权衡
例子:
loop unrolling: 减少循环的判断
优化是为了控制速度,空间和tradeoff。提供了一些优化选项
-OLEVEL(这里的O值optimization的意思) 的LEVEL的值是从0到3,值越大等级越高。但付出的代价也越高,且速度也不一定是最快的。(也许会增加debug的难度,因为优化也许会把你的源代码改的面目犬吠)
gcc -Wall -O1 test.c -o O1{for (i = 1;i < 1000000;i ++) sum += i;}
-funroll-loops优化循环
gcc -Wall -O1 -funroll-loop test.c -o O1{for (i = 1;i < 1000000;i ++) sum += i;}
gcc允许优化和debug(debug和优化是一对矛盾,通常debug时把优化关掉)
默认的gcc选项是-g和-O2(for GNU release)
g++编译c++
g++直接把c++ source code 转化为汇编。而一些其他的是把c++先转换为c再转化为汇编
编译c++用g++,因为g++和gcc是两个不通的程序(从which gcc 和whic g++就能看出来)
c的命名空间就一个
the sequence of commands executed by a single invocation of GCC consists of the following stages:
preprocessing(to expand macros) cpp
compilation (from source code to assembly language) gcc
assembly (from assembly language to machine code) 汇编器 as
linking (to create the final executalbe) 链接器 gcc
preprocessing GCC调用cpp
cpp hello.c > hello.i 其中hello.i把hello.c中所有的宏都替换掉了
如果是g++的话应该是以.ii结尾。除非使用-save-temps否则这个文件不会被保留
the compiler(最复杂的一步,因为汇编语言和机器码几乎是一一对应的)
-S使gcc把文件变成汇编语言,而不产生目标文件(object file)
gcc -Wall -S hello.i
the assembler
as hello.s -o hello.o
the linker
gcc hello.o
or g++ hello.o
-v是vervose的意思,把详细的信息打印出来
gcc -Wall -v hello.c
nm a.out 能查看symbol table(符号表)
the table stores the location of functions and variables by name ,and can be displayed with nm command.
符号表,能通过名字查看变量和函数的地址
T代表被定义了,U代表没有被定义,必须依赖于外部。使用动态库就会有U。nm可一帮助查看某个函数是在否是在库里定义的,如果是T就代表是在这个库里定义的,否则不是。
ldd a.out 能查看缺少哪些动态库。可以使用LD_LIBRARY_PATH=需要的库的位置:$LD_LIBRARY_PATH
两个工具,gprof和gcov(profile和coverage)
gprof查看每个函数的执行时间,百分比和执行次数
gcc -Wall -pg hello.c
./a.out
然后发现多了一个gmon.out文件,然后:
gprof a.out就能看到每个函数的执行时间%比,执行时间
gcov查看每行代码的执行次数(没有使用是五个#)
gcc -Wall -fprofile-arcs -ftest-coverage hello.c
产生一个.gcno文件然后
./a.out
然后:
gcov hello.c(源文件)
然后vi hello.c.gcov
就能看到,每一行的执行次数
阅读(1096) | 评论(0) | 转发(0) |