gcc tips - GCC使用技巧与高级特性

17 篇文章 0 订阅

目录

1. 获取 GCC 编译器预定义的宏

2. 列出依赖的头文件

3. 保存预处理结果到文件(展开define, 展开include header)

4. 写回调跟踪记录函数运行 -finstrument-functions

5. -fdump-rtl-expand 画函数调用关系图


GCC,全称GNU Compiler Collection,是一套功能强大的开源编译器,支持多种编程语言,如C、C++、Fortran、Objective-C、Ada等。GCC的灵活性和可移植性使得它在各种系统和项目中都有广泛的应用。然而,要充分利用GCC的全部潜力,需要熟悉一些高级特性和使用技巧。在本文中,我们将探讨一些GCC的进阶用法,帮助开发者优化代码、提高编译效率并减少潜在错误。

1. 获取 GCC 编译器预定义的宏

  • -E: 只运行预处理器。这意味着编译器将只处理源文件中的预处理器指令(例如 #include#define 等),然后输出预处理后的代码。
  • -dM: 输出所有的宏定义。当与 -E 一起使用时,这将输出编译器预定义的所有宏。
[root]# gcc -E -dM -</dev/null
#define __DBL_MIN_EXP__ (-1021)
#define __FLT32X_MAX_EXP__ 1024
#define __UINT_LEAST16_MAX__ 0xffff
#define __ATOMIC_ACQUIRE 2
#define __FLT128_MAX_10_EXP__ 4932
#define __FLT_MIN__ 1.17549435082228750796873653722224568e-38F
#define __GCC_IEC_559_COMPLEX 2
#define __UINT_LEAST8_TYPE__ unsigned char
#define __SIZEOF_FLOAT80__ 16
#define __INTMAX_C(c) c ## L
#define __CHAR_BIT__ 8
#define __UINT8_MAX__ 0xff
#define __WINT_MAX__ 0xffffffffU
#define __FLT32_MIN_EXP__ (-125)
#define __ORDER_LITTLE_ENDIAN__ 1234
#define __SIZE_MAX__ 0xffffffffffffffffUL
#define __WCHAR_MAX__ 0x7fffffff
#define __GCC_HAVE_SYNC_COMPARE_AND_SWAP_1 1
#define __GCC_HAVE_SYNC_COMPARE_AND_SWAP_2 1
#define __GCC_HAVE_SYNC_COMPARE_AND_SWAP_4 1
#define __DBL_DENORM_MIN__ ((double)4.94065645841246544176568792868221372e-324L)
#define __GCC_HAVE_SYNC_COMPARE_AND_SWAP_8 1
#define __GCC_ATOMIC_CHAR_LOCK_FREE 2
#define __GCC_IEC_559 2

2. 列出依赖的头文件

用于生成文件的依赖关系。这个选项对于大型项目特别有用,因为它可以帮助你跟踪哪些头文件被哪个源文件包含,以及当头文件更改时哪些源文件需要重新编译。

当你使用 gcc -M 选项时,GCC 会输出一个规则集,这个规则集描述了源文件和目标文件之间的依赖关系。输出的规则可以直接被 make 工具使用,从而自动化构建过程。

$ gcc -M sizeofstruct.c
	  sizeofstruct.o: sizeofstruct.c /usr/include/stdc-predef.h \
	 /usr/include/stdio.h /usr/include/features.h /usr/include/sys/cdefs.h \
	 /usr/include/bits/wordsize.h /usr/include/gnu/stubs.h \
	 /usr/include/gnu/stubs-64.h \
	 /usr/lib/gcc/x86_64-redhat-linux/4.8.5/include/stddef.h \
	 /usr/include/bits/types.h /usr/include/bits/typesizes.h \
	 /usr/include/libio.h /usr/include/_G_config.h /usr/include/wchar.h \
	 /usr/lib/gcc/x86_64-redhat-linux/4.8.5/include/stdarg.h \
	 /usr/include/bits/stdio_lim.h /usr/include/bits/sys_errlist.h

3. 保存预处理结果到文件(展开define, 展开include header)

[root]# cat test_e.c
#include<unistd.h>

int main(int argc, char** argv){
        printf("Hello world");
        return 0;
}

# gcc -E test_e.c -o test_e.i

[root]# more test_e.i
# 1 "test_e.c"
# 1 "<built-in>"
# 1 "<command-line>"
# 31 "<command-line>"
# 1 "/usr/include/stdc-predef.h" 1 3 4
# 32 "<command-line>" 2
# 1 "test_e.c"
# 1 "/usr/include/unistd.h" 1 3 4
# 25 "/usr/include/unistd.h" 3 4
# 1 "/usr/include/features.h" 1 3 4
# 428 "/usr/include/features.h" 3 4
# 1 "/usr/include/sys/cdefs.h" 1 3 4
# 442 "/usr/include/sys/cdefs.h" 3 4
# 1 "/usr/include/bits/wordsize.h" 1 3 4
# 443 "/usr/include/sys/cdefs.h" 2 3 4
# 1 "/usr/include/bits/long-double.h" 1 3 4
# 444 "/usr/include/sys/cdefs.h" 2 3 4
# 429 "/usr/include/features.h" 2 3 4
# 452 "/usr/include/features.h" 3 4
# 1 "/usr/include/gnu/stubs.h" 1 3 4
# 10 "/usr/include/gnu/stubs.h" 3 4
# 1 "/usr/include/gnu/stubs-64.h" 1 3 4
# 11 "/usr/include/gnu/stubs.h" 2 3 4
# 453 "/usr/include/features.h" 2 3 4
# 26 "/usr/include/unistd.h" 2 3 4


# 202 "/usr/include/unistd.h" 3 4
# 1 "/usr/include/bits/posix_opt.h" 1 3 4
# 203 "/usr/include/unistd.h" 2 3 4



# 1 "/usr/include/bits/environments.h" 1 3 4
...

[root]# wc test_e.i
 1416  2357 24475 test_e.i

4. 写回调跟踪记录函数运行 -finstrument-functions

具体见老外写的一篇blog

我们组曾经用此跟踪过一个很棘手的问题。细节先不谈。

5. -fdump-rtl-expand 画函数调用关系图

用于在编译过程中输出 RTL(Register Transfer Language)扩展阶段的中间表示。

当使用这个选项时,GCC 会在编译过程中生成一个包含 RTL 扩展阶段信息的文本文件。这个文件以源文件的扩展名为基础,添加了 .rtl-expand 后缀。例如,如果你正在编译名为 foo.c 的源文件,生成的 RTL 扩展文件将会是 foo.c.rtl-expand

RTL 是 GCC 内部表示的一种中间语言,用于在编译过程中的不同阶段之间传递信息。RTL 扩展阶段是 RTL 转换过程的一部分,其中将高级 RTL 指令转换为更低级别的 RTL 指令,以便后续的机器代码生成阶段。

我曾经用过此编译选项来结合Egypt来画函数调用关系图,直接引用egypt给的一个例子

  • 23
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

深山老宅

鸡蛋不错的话,要不要激励下母鸡

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值