宏忽略最后一个参数

时间:2016-07-16 23:58:01

标签: c++ macros

我写了一个宏来替换循环,但我意识到当我把最后一个参数留空时它才有效。

f(i, 0, 3) cout<<i;
output: 012

f(i, 3, =5) cout<<i;
output: 345

f(i, 4, 2) cout<<i;
output: 43

f(i, 3, ) cout<<i;
output: 321 //it understands that the limit is 0

我想知道为什么会发生,如果可以用第二个或第一个参数完成

这是宏,它非常大,所以我会分成行

#define f(v, s, e) for(int v=s,                  \        s is the start value      
                           L1=atoi(&#e[0]),      \        L1 is the end value
                           K=s<L1?1:-1,                         \ K stores if s<e
                           L=L1+(#e[sizeof(#e)-2]=='='?K:0);    \ trick to check <= and >=
                           v!=L; v+= K)                       condition and increasing

2 个答案:

答案 0 :(得分:2)

好吧,让我们看一下宏观扩张,不管吗?

atoi("=5")

所以发生了什么,当你把第三个参数留空时,它将字符串化为空字符串,而""[sizeof("")-2]返回0.注意""[-1]也评估为零,其中我认为不是你所期望的。另请注意,{{1}}等同于{{1}},它会引发未定义的行为。总而言之,这实际上并不起作用,它似乎偶然起作用。

第一个和第二个参数在没有字符串化的情况下使用,因此将它们留空将是语法错误。

有人可以想象出一些聪明的模板,它可以做你想要的这个,但是你必须告诉我们当第一个和第二个参数时应该是什么行为是空的。

编辑抛开:请不要把这样的代码放在&#34;真实&#34;软件。另一方面,如果您正在处理IOCCC提交,请狂野。

答案 1 :(得分:1)

e是一个空标记列表时,#e是一个空字符串文字,""atoi(&#e[0])有效atoi(""),或0(atoi出错时返回0)。

#e[sizeof(#e)-2]扩展为""[sizeof("")-2],展示未定义的行为。空字符串文字的类型为const char[1],其大小为1,因此您尝试访问-1的索引。