忽略最后一个参数的宏
Macro ignoring last parameter
我写了一个宏来替换循环,但是当我将最后一个参数留空时,我意识到它有效。
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
好吧,让我们看看宏观扩展,好吗?
// f(i, 0, 3) cout<<i;
for(int i=0,
L1=atoi(&"3"[0]),
K=0<L1?1:-1,
L=L1+("3"[sizeof("3")-2]=='='?K:0);
i!=L;
i+= K) cout<<i;
// f(i, 3, =5) cout<<i;
for(int i=3,
L1=atoi(&"=5"[0]),
K=3<L1?1:-1,
L=L1+("=5"[sizeof("=5")-2]=='='?K:0);
i!=L; i+= K) cout<<i;
// f(i, 4, 2) cout<<i;
for(int i=4,
L1=atoi(&"2"[0]),
K=4<L1?1:-1,
L=L1+("2"[sizeof("2")-2]=='='?K:0);
i!=L; i+= K) cout<<i;
// f(i, 3, ) cout<<i;
for(int i=3,
L1=atoi(&""[0]),
K=3<L1?1:-1,
L=L1+(""[sizeof("")-2]=='='?K:0);
i!=L; i+= K) cout<<i;
所以发生的情况是,当你将第三个参数留空时,它会字符串化为空字符串,atoi("")
返回 0。 请注意,atoi("=5")
的计算结果也为零,我认为这不是您所期望的。 另请注意,""[sizeof("")-2]
等效于引发未定义行为的""[-1]
。 总之,这实际上并没有奏效,它只是偶然地似乎奏效了。
使用第一个和第二个参数时没有字符串化,因此将它们留空将是一个语法错误。
可以想象,有人可以想出一些聪明的模板来做你想要它做的事情,但你必须告诉我们当第一个和第二个参数为空时的行为应该是什么。
撇开社论不谈:请不要把这样的代码放在"真正的"软件中。 另一方面,如果您正在处理IOCCC提交的内容,请疯狂。
当 e
是空的标记列表时,#e
是一个空字符串文字,""
. 然后atoi(&#e[0])
有效地atoi("")
,或 0(atoi
错误时返回 0)。
#e[sizeof(#e)-2]
扩展到""[sizeof("")-2]
,表现出未定义的行为。空字符串文字的类型为 const char[1]
,其大小为 1,因此您正在尝试访问 -1 的索引。
相关文章:
- 更改可变参数模板中的最后一个类型
- 这种获取模板参数包中最后一个元素的方法是否有隐藏的开销?
- C++模板:无法匹配可变参数类模板中的最后一个模板
- 如何更改参数包中的最后一个参数
- 模板参数重载,最后一个参数为非类型名
- 有没有办法访问除最后一个模板参数之外的所有内容
- 此模板函数上的最后一个参数有什么用?
- 如何在参数包不是最后一个参数的C++中编写可变参数模板函数?
- C :为什么它总是首先执行最后一个参数
- std::transform的最后一个参数
- C++模板部分特化:为什么我无法匹配可变参数模板中的最后一个类型
- 默认参数模板与可变参数模板:最后一个模板参数是什么
- 将除最后一个作为变量类型的变量外的所有可变模板参数解包
- 可变参数模板参数始终必须是最后一个
- 基于最后一个参数值的构造函数
- 最后一个参数将覆盖 SQLite 绑定中的先前参数
- 函数模板的非最后一个默认模板参数
- 通过去掉最后一个参数,将c++中的for(a;b;c)简化为for(x;y;)
- 当可变参数模板不是最后一个参数时,如何重载它们
- 默认参数:只能保留最后一个参数