井号--数字--文件名

最近研究Lighttpd的源代码,发现代码中有很多宏定义,不直观,而且有的相当晦涩难懂。对付宏定义,其实有个偷懒的方法就是使用GCC的预编译机制,将它们展开,保存展开后的源代码,这样读起来就清晰多了。说白了就是使用gcc -E命令。
比如有个源代码文件google.c,内容如下:

struct sttest
{
	int a;
};

int main()
{
	#define INIT_STRUCT(st, value) st.a = value

	struct sttest st1 , st2;
	INIT_STRUCT(st1, 4);
	INIT_STRUCT(st2, 5);
	return 0;
}


使用gcc命令得到展开后等价的源代码:gcc -E google.c > google_ext.c。google_ext.c文件内容如下:

# 1 "google.c"
# 1 "<built-in>"
# 1 "<command line>"
# 1 "google.c"
struct sttest
{
	int a;
};

int main()
{


	struct sttest st1 , st2;
	st1.a = 4;
	st2.a = 5;
	return 0;
}
 

显而易见原来宏定义:INIT_STRUCT(st1,4);,已经被等价展开,这样读起来岂不是要易懂的多了?!不过,我也发现了个问题,就是# 1 "google.c"这种代码啥意思?看起来挺怪的。
对此做个小试验,编写测试代码如下:

#include <stdio.h>

int main()
{
	printf("A:%s>>%s>>%d\n", __FILE__, __FUNCTION__, __LINE__);	//源文件行号:5
	# 100
	printf("B:%s>>%s>>%d\n", __FILE__, __FUNCTION__, __LINE__);	//源文件行号:7
	# 1000
	printf("C:%s>>%s>>%d\n", __FILE__, __FUNCTION__, __LINE__);	//源文件行号:9
	printf("D:%s>>%s>>%d\n", __FILE__, __FUNCTION__, __LINE__);	//源文件行号:10
	# 10000 "new_file_name.c"
	printf("E:%s>>%s>>%d\n", __FILE__, __FUNCTION__, __LINE__);	//源文件行号:12
	printf("F:%s>>%s>>%d\n", __FILE__, __FUNCTION__, __LINE__);	//源文件行号:13
	return 0;
}


 

将代码保存为test.c,编译执行,程序输出如下:

A:test.c>>main>>5
B:test.c>>main>>100
C:test.c>>main>>1001
D:test.c>>main>>1003
E:new_file_name.c>>main>>10000
F:new_file_name.c>>main>>10001

至此我们可以得出一个结论,像# 1 "google.c"这种伪代码的作用就是,标示紧跟其后一行代码的行号和文件名,并且对其后所有行均起作用,使得所有行都以该数字为基准重新编号

posted @ 2009-09-02 00:16  酱油和醋  阅读(756)  评论(1编辑  收藏  举报