免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 793 | 回复: 0
打印 上一主题 下一主题

LINUX C里面的#和##语法解释 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2007-10-21 17:51 |只看该作者 |倒序浏览
今天看LINUX内核代码的时候,忽然又看到了#及##的出现,很奇怪的语法,以前的贴子里我点了一下##的用法,但没有去查相关的文档,至于#这里不将那个预处理的作用,先看一下代码示例:
      1 #include
      2
      3 #define TEST_NUM  6
      4
      5 #define VAR2STR(var) #var
      6 #define JOIN(x, y) x##y
      7
      8 int main(int argv, char* argc[])
      9 {
     10     printf("%s: %d\n",VAR2STR(TEST_NUM),JOIN(TEST_, NUM));
     11     return 0;
     12 }
这里面用了这两个符号,下面看一下预处理过后的代码:
               .......
    938 int main(int argv, char* argc[])
    939 {
    940     printf("%s: %d\n","TEST_NUM",6);
    941     return 0;
    942 }
再看一下运行结果:
[root@works]# ./test
TEST_NUM: 6
#及##在这一段代码里的作用表现为:
#将紧接后面的无素(遇到空白视为一个元素),转化为字符串,而##则起到连结的作用.
看一下LINUX标准里面对它们的解释,没有翻译,直接COPY过来的,来自ISO-IEC1999文件:
=====================================================================
6.10.3.1 Argument substitution
1 After the arguments for the invocation of a function-like macro have been identified,argument substitution takes place. A parameter in the replacement list, unless preceded by a # or ## preprocessing token or followed by a ## preprocessing token (see below), is replaced by the corresponding argument after all macros contained therein have been expanded. Before being substituted, each argument’s preprocessing tokens are completely macro replaced as if they formed the rest of the preprocessing file; no other preprocessing tokens are available.
2 An identifier _ _VA_ARGS_ _ that occurs in the replacement list shall be treated as if it were a parameter, and the variable arguments shall form the preprocessing tokens used to replace it.
6.10.3.2 The # operator
Constraints
1 Each # preprocessing token in the replacement list for a function-like macro shall be followed by a parameter as the next preprocessing token in the replacement list.
Semantics
2 If, in the replacement list, a parameter is immediately preceded by a # preprocessing token, both are replaced by a single character string literal preprocessing token that contains the spelling of the preprocessing token sequence for the corresponding argument. Each occurrence of white space between the argument’s preprocessing tokens becomes a single space character in the character string literal. White space before the first preprocessing token and after the last preprocessing token composing the argument is deleted. Otherwise, the original spelling of each preprocessing token in the argument is retained in the character string literal, except for special handling for producing the spelling of string literals and character constants: a \ character is inserted before each " and \ character of a character constant or string literal (including the delimiting "
characters), except that it is implementation-defined whether a \ character is inserted before the \ character beginning a universal character name. If the replacement that results is not a valid character string literal, the behavior is undefined. The character string literal corresponding to an empty argument is "". The order of evaluation of # and ## operators is unspecified.
6.10.3.3 The ## operator
Constraints
1 A## preprocessing token shall not occur at the beginning or at the end of a replacement list for either form of macro definition.
Semantics
2 If, in the replacement list of a function-like macro, a parameter is immediately preceded or followed by a ## preprocessing token, the parameter is replaced by the corresponding argument’s preprocessing token sequence; however, if an argument consists of no preprocessing tokens, the parameter is replaced by a placemarker preprocessing token instead.145)
3 For both object-like and function-like macro invocations, before the replacement list is reexamined for more macro names to replace, each instance of a ## preprocessing token in the replacement list (not from an argument) is deleted and the preceding preprocessing token is concatenated with the following preprocessing token. Placemarker preprocessing tokens are handled specially: concatenation of two placemarkers results in a single placemarker preprocessing token, and concatenation of a placemarker with a non-placemarker preprocessing token results in the non-placemarker preprocessing token. If the result is not a valid preprocessing token, the behavior is undefined. The resulting token is available for further macro replacement. The order of evaluation of ## operators is unspecified.
4 EXAMPLE
In the following fragment:
#define hash_hash # ## #
#define mkstr(a) # a
#define in_between(a) mkstr(a)
#define join(c, d) in_between(c hash_hash d)
char p[] = join(x, y); // equivalent to
// char p[] = "x ## y";
The expansion produces, at various stages:
join(x, y)
in_between(x hash_hash y)
in_between(x ## y)
mkstr(x ## y)
"x ## y"
In other words, expanding hash_hash produces a new token, consisting of two adjacent sharp signs, but
this new token is not the ## operator.
               
               
               

本文来自ChinaUnix博客,如果查看原文请点:http://blog.chinaunix.net/u1/37836/showart_404712.html
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP