使用 array(or initializer_list) 技巧解包 variadic 是优化安全的吗?
Is unpacking variadic using array(or initializer_list) trick optimize-safe?
由于 C++14 不能使用折叠表达式,为了创建一个在每个可变参数上调用 bar
的函数,必须使用函数重载。
template<typename Arg>
void foo(Arg arg) {
bar(arg);
}
template<typename Arg, typename ...Args>
void foo(Arg arg, Args... args) {
bar(arg);
foo(args...);
}
但是在括号中使用逗号运算符和括号,可以在不重载的情况下解包。
template<typename ...Args>
void foo(Args... args) {
int dummy[] = {
(bar(args), 0)...
};
}
它按预期运行良好,但我的编译器总是警告我未使用 dummy
。
所以我担心编译器会删除 dummy
(因为它未被使用并且实际上仅由文字初始化),并导致不调用 bar
.
或者只是将 dummy
声明为 volatile
就足以保证调用 bar
?
我知道有 [[maybe_unused]]
属性,但它也是 C++17 特性。
不用担心,编译器优化不会破坏代码行为,否则编译器会被破坏,但是存在复制省略等以记录的方式改变行为。
在您的情况下,将评估调用并丢弃存储在数组中的 return 值。因为这是您的意图,您可以使用变量 !
来消除此警告
((void)dummy);
So I'm worried that the compiler removes dummy
(since it's unused and actually initialized only by literals), and resulting to not calling bar
.
编译器可能会删除 dummy
但不能删除 bar
调用,如果它们有副作用(对于递归版本)。
所以你很安全。
Or just declaring dummy
as volatile
"
那是最糟糕的。当你强制写入时。您以错误的方式删除了警告。
I know that there is [[maybe_unused]]
attribute, but it's also C++17 feature.
转换为 void
是以前删除警告的常用方法。
由于 C++14 不能使用折叠表达式,为了创建一个在每个可变参数上调用 bar
的函数,必须使用函数重载。
template<typename Arg>
void foo(Arg arg) {
bar(arg);
}
template<typename Arg, typename ...Args>
void foo(Arg arg, Args... args) {
bar(arg);
foo(args...);
}
但是在括号中使用逗号运算符和括号,可以在不重载的情况下解包。
template<typename ...Args>
void foo(Args... args) {
int dummy[] = {
(bar(args), 0)...
};
}
它按预期运行良好,但我的编译器总是警告我未使用 dummy
。
所以我担心编译器会删除 dummy
(因为它未被使用并且实际上仅由文字初始化),并导致不调用 bar
.
或者只是将 dummy
声明为 volatile
就足以保证调用 bar
?
我知道有 [[maybe_unused]]
属性,但它也是 C++17 特性。
不用担心,编译器优化不会破坏代码行为,否则编译器会被破坏,但是存在复制省略等以记录的方式改变行为。
在您的情况下,将评估调用并丢弃存储在数组中的 return 值。因为这是您的意图,您可以使用变量 !
来消除此警告((void)dummy);
So I'm worried that the compiler removes
dummy
(since it's unused and actually initialized only by literals), and resulting to not callingbar
.
编译器可能会删除 dummy
但不能删除 bar
调用,如果它们有副作用(对于递归版本)。
所以你很安全。
Or just declaring
dummy
asvolatile
"
那是最糟糕的。当你强制写入时。您以错误的方式删除了警告。
I know that there is
[[maybe_unused]]
attribute, but it's also C++17 feature.
转换为 void
是以前删除警告的常用方法。