这两天听一个老外讲师讲Linux Compile和Debug的Training,看到一些有意思的东西,找了点资料,写出来.算是第一篇有点意义的文章.
这两个宏以前都没见过,据说都是内核里常用的东东,厄,确实接触得少.
首先是__stringify宏:
g了一下,找到一篇文章,以下内容都是转载,仅经过验证和整理,粘出内容:
宏定义:
在 linux/stringify.h中
[url=http://gcc.gnu.org/onlinedocs/cpp/Argument-Prescan.html#Argument-Prescan]更深入的解释:[/url]
If an argument is stringified or concatenated, the prescan does not occur. If you want to expand a macro, then stringify or concatenate its expansion, you can do that by causing one macro to call another macro that does the stringification or concatenation. For instance, if you have
then AFTERX(BUFSIZE) expands to X_BUFSIZE, and XAFTERX(BUFSIZE) expands to X_1024. (Not to X_TABLESIZE. Prescan always does a complete expansion.)
OK,简而言之,就是C CPreprocessor对字符串连接宏不做深入展开.
__attribute__宏:
号称GNU C中最好feature之一...
GCC Manual里三则文章:
[url=http://gcc.gnu.org/onlinedocs/gcc-4.0.0/gcc/Function-Attributes.html]GCC 4.0 Function Attributes[/url]
[url=http://gcc.gnu.org/onlinedocs/gcc-4.0.0/gcc/Variable-Attributes.html]GCC 4.0 Variable Attributes[/url]
[url=http://gcc.gnu.org/onlinedocs/gcc-4.0.0/gcc/Type-Attributes.html]GCC 4.0 Type Attributes[/url]
感觉Function-Attributes里的format,noreturn以及Variable-Attributes里的aligned和shared应该用得比较多.
最后附老外代码里拿Variable-Attributes中的section做调试跟踪管理文件的片段:
这两个宏以前都没见过,据说都是内核里常用的东东,厄,确实接触得少.
首先是__stringify宏:
g了一下,找到一篇文章,以下内容都是转载,仅经过验证和整理,粘出内容:
宏定义:
在 linux/stringify.h中
#ifndef __LINUX_STRINGIFY_H
#define __LINUX_STRINGIFY_H
/* Indirect stringification. Doing two levels allows the parameter to be a
* macro itself. For example, compile with -DFOO=bar, __stringify(FOO)
* converts to "bar".
*/
#define __stringify_1(x) #x
#define __stringify(x) __stringify_1(x)
#endif /* !__LINUX_STRINGIFY_H */
[url=http://gcc.gnu.org/onlinedocs/cpp/Argument-Prescan.html#Argument-Prescan]更深入的解释:[/url]
If an argument is stringified or concatenated, the prescan does not occur. If you want to expand a macro, then stringify or concatenate its expansion, you can do that by causing one macro to call another macro that does the stringification or concatenation. For instance, if you have
#define AFTERX(x) X_ ## x
#define XAFTERX(x) AFTERX(x)
#define TABLESIZE 1024
#define BUFSIZE TABLESIZE
then AFTERX(BUFSIZE) expands to X_BUFSIZE, and XAFTERX(BUFSIZE) expands to X_1024. (Not to X_TABLESIZE. Prescan always does a complete expansion.)
OK,简而言之,就是C CPreprocessor对字符串连接宏不做深入展开.
__attribute__宏:
号称GNU C中最好feature之一...
GCC Manual里三则文章:
[url=http://gcc.gnu.org/onlinedocs/gcc-4.0.0/gcc/Function-Attributes.html]GCC 4.0 Function Attributes[/url]
[url=http://gcc.gnu.org/onlinedocs/gcc-4.0.0/gcc/Variable-Attributes.html]GCC 4.0 Variable Attributes[/url]
[url=http://gcc.gnu.org/onlinedocs/gcc-4.0.0/gcc/Type-Attributes.html]GCC 4.0 Type Attributes[/url]
感觉Function-Attributes里的format,noreturn以及Variable-Attributes里的aligned和shared应该用得比较多.
最后附老外代码里拿Variable-Attributes中的section做调试跟踪管理文件的片段:
//EXTRA_CMDS=echo -DCHECKSUM=`md5sum SOURCE | cut -f 1 -d " "` -DHOST=`hostname` -DUSER=$USER -DSYSTEM=`uname -a | tr ' ' '-'`
// this macro does two things:
// - makes sure that the compiler does not issue "unused variable" or tried to make
// the static variable go away just because no one is using it.
// - make sure that our data goes into it's own section of the object code.
#define SECTION ".compile_info"
#define ATTR __attribute__((section(SECTION),used))
// the static allows us to use a compiled on tag for each file so you can put it in a common
// header and get stamping for all files in your project.
static const char* ATTR id_file="id_file=" __FILE__;
static const char* ATTR id_base_file="id_base_file=" __BASE_FILE__;
static const char* ATTR id_host="id_host=" __stringify(HOST);
static const char* ATTR id_user="id_user=" __stringify(USER);
static const char* ATTR id_system="id_system=" __stringify(SYSTEM);
static const char* ATTR id_date="id_date=" __DATE__;
static const char* ATTR id_time="id_time=" __TIME__;
static const char* ATTR id_timestamp="id_timestamp=" __TIMESTAMP__;
static const char* ATTR id_string_version="id_string_version=" STRING_VERSION;
static const char* ATTR id_numeric_version="id_numeric_version=" __stringify(NUMERIC_VERSION);
static const char* ATTR id_checksum="id_checksum=" __stringify(CHECKSUM);
static const char* ATTR id_version="id_version=" __VERSION__;