当然,这个“惊人”其实惊的是我。本文记录一些之前居然没有注意到LUNUX/C语言中的奇特现象。
1. 条件运算符的简化版
例如标准的做法:printf("%d\n", 1?1:0); 将输出1
而 gcc 允许简化为:printf("%d\n", 1?:0); ,即省略了第二个参数1,这时仍然会输出1!
即:当a为非零值时,a?:b 的值为a,否则为b。
注意1:该做法不是标准C语言允许的,而是gcc优化支持的,即仅在gcc环境有效。
注意2:a?a:b与a?:b并不完全等价,例如 a++?a++:b 中a为真时a++将执行两次,而 a++?:b 中只会执行一次。
附:GCC的说明文档
2. sizeof后面的括号不是必须的
由于 sizeof 实际是个运算符(就跟+-*/差不多!),而不是函数,所以括号不是必须的。
例如 printf("%d\n", sizeof short); 能正常输出 2
3. 在每个函数进入和退出时执行指定的函数(像python装饰器一样!)
gcc的编译选项 -finstrument-functions,然后每个函数进入和退出时都会分别调用以下两个函数:
void __cyg_profile_func_enter(void *this_fn, void *call_site); void __cyg_profile_func_exit(void *this_fn, void *call_site);
自己在代码中实现这2个函数即可。
如果不想让某些函数(例如函数test_func)调用这2个函数,可以用声明函数属性为 no_instrument_function:
void test_func() __attribute__((no_instrument_function)) { }
4. LD_PRELOAD实现库函数定义覆盖
使用LD_PRELOAD能使程序首先加载指定的库,例如执行:
shell>LD_PRELOAD=/tmp/libtest.so ./test
将预先加载/tmp/libtest.so并运行test程序,加入libtest.so中定义了malloc/realloc/calloc/free函数,则test中进行内存申请和释放时都会调用libtest.so中的函数(而不是C库中的),
可对test中内存情况进行跟踪调试。
创建于 2019-05-09 10:33:52
最后更新于 2019-08-20 09:26:47