Benjamin

静以修身,俭以养德,非澹薄无以明志,非宁静无以致远。
随笔 - 397, 文章 - 0, 评论 - 196, 引用 - 0
数据加载中……

标C中空宏的妙用

偶然的机会,看到了下面的C代码:
ISC_PLATFORM_NORETURN_PRE static void
library_fatal_error(const char *file, int line, const char *format,
      va_list args)
ISC_FORMAT_PRINTF(3, 0) ISC_PLATFORM_NORETURN_POST;
其中ISC_PLATFORM_NORETURN_PRE 和ISC_PLATFORM_NORETURN_POST,ISC_FORMAT_PRINTF是宏。具体定义如下:
#define ISC_PLATFORM_NORETURN_PRE __declspec(noreturn)
#define ISC_PLATFORM_NORETURN_POST
#define ISC_FORMAT_PRINTF(fmt, args) __attribute__((__format__(__printf__, fmt, args)))(GCC中设置函数属性、变量属性、类型属性的一种机制,用来设置在这个宏前面的有关函数的一些属性)。
这段代码是一个老外写的,编译也没有错误;可这样的语法却很少见(在函数的末尾加上了一个空宏)。
这里ISC_PLATFORM_NORETURN_POST就是所谓的空宏,空宏(未定义的宏)都展开为空字符串,但定义为空字符串的宏被视为是在预处理表达式定义的,一般的用法是在#ifdef/#endif和#ifndef/#endif的条件编译语句中。#ifdef/#endif判断ifdef后面的宏是否定义,如果定义了,则对下面的代码或语句编译,是有条件的编译;#ifndef/#endif和#define配合使用,取消定义用undef宏,作用和#ifdef/#endif基本一样。

但是像这样放在函数的末尾还是不多见的,在预编译时,空宏将被替换成一个空字符串,它的值是0.这里的空宏只是为了增加代码的可读性,起注释、说明的作用,其实完全可以不加的,完全可有可无的,但是加上了,看起来能更清晰些。;而且这两个宏一般都是配对使用的(空宏也可以放在函数的开头)。
 

posted on 2010-06-06 00:19 Benjamin 阅读(4669) 评论(4)  编辑 收藏 引用 所属分类: C/C++

评论

# re: 标C中空宏的妙用  回复  更多评论   

可以举个调用的例子吗?
2010-06-06 12:34 | 六翼天使

# re: 标C中空宏的妙用  回复  更多评论   

很多见 用来条件编译等
2010-06-07 08:36 | 万连文

# re: 标C中空宏的妙用  回复  更多评论   

条件编译中是常见,可放到函数末尾却不多见;在条件编译中是判断宏是否定义,和这里的语境不同。
2010-06-07 20:55 | Benjamin

# re: 标C中空宏的妙用  回复  更多评论   

条件编译

#if (1) 这里改成1和0编译试试就知道了
# define FUNCTION_BEGIN __declspec(noreturn)
# define FUNCTION_END const
#else
# define FUNCTION_BEGIN
# define FUNCTION_END
#endif

class test {
public:
FUNCTION_BEGIN int hello() FUNCTION_END;

private:
int _summy;
};

FUNCTION_BEGIN int test::hello() FUNCTION_END {
_summy = 0;
return printf("hello");
}
2010-06-08 17:16 | kevin_chou

只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理