`

macro __stringify & __attribute__

阅读更多
这两天听一个老外讲师讲Linux Compile和Debug的Training,看到一些有意思的东西,找了点资料,写出来.算是第一篇有点意义的文章.
这两个宏以前都没见过,据说都是内核里常用的东东,厄,确实接触得少.
首先是__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 */

更深入的解释:
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里三则文章:
GCC 4.0 Function Attributes
GCC 4.0 Variable Attributes
GCC 4.0 Type Attributes
感觉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__;
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics