sizeof可以应用于未捕获的变量上的lambda,或者这是一个编译器错误? [英] Can sizeof be applied inside a lambda on a variable that is not captured or is this a compiler bug?
问题描述
这是在这里找到的讨论的后续。
以下代码在gcc和clang( live demo )下编译。这在行 // 1
中的情况是令人惊讶的,因为lambda不捕获任何东西。对于 MCR2
的情况,其中lambda返回指针本身,我们得到期望的编译时错误(行 //将不编译
)。如何应用运算符 sizeof
与返回指针不同?
The following code compiles both under gcc and clang (live demo). This is surprising for the case in line //1
since the lambda does not capture anything. For the case of MCR2
, where the lambda returns the pointer itself, we get the expected compile time error (line // Will not compile
). How is application of operator sizeof
different from returning the pointer?
#include <iostream>
#define MCR1(s) \
([]() { return sizeof(s); })()
#define MCR2(s) \
([]() { return s; })()
int main() {
auto *s= "hello world";
auto x1 = MCR1( s ); //1
auto y1 = MCR1( "hello world" );
// auto x2= MCR2( s ); // Will not compile
auto y2= MCR2( "hello world" );
std::cout << x1 << " " << y1 << '\n';
std::cout // << x2 << " "
<< y2 << '\n';
}
继续讨论这里是另一个例子。令人惊讶的是,标记为 // 2
的行现在在gcc7(开发版本)(现场演示)。这里的区别在于表达式现在标记为 constexpr
。
Following up on the discussion here is another example. Surprisingly, the line marked //2
now compiles under gcc7 (development version) (live demo). The difference here is that expressions are marked constexpr
, now.
#include <iostream>
#define MCR1(s) \
([]() { return sizeof(s); })()
#define MCR2(s) \
([]() { return s; })()
int main() {
auto constexpr *s= "hello world";
auto constexpr x1= MCR1( s );
auto constexpr y1= MCR1( "hello world" );
auto constexpr x2= MCR2( s ); //2
auto constexpr y2= MCR2( "hello world" );
std::cout << x1 << " " << y1 << '\n';
std::cout << x2 << " " << y2 << '\n';
}
推荐答案
的)上下文的评价。 sizeof
未评估。
The difference is the (lack of) evaluation of context. sizeof
is unevaluated.
根据N3337(≈C++ 11)
As per N3337 (≈C++11)
§5.12 [expr.prim.lambda] / 11
§5.1 2 [expr.prim.lambda] / 11
如果一个具有关联的捕获默认及其
复合语句 odr-使用 this
具有自动存储持续时间的变量和odr使用的实体没有被显式捕获,
然后odr使用的实体被说成是隐式捕获;
If a lambda-expression has an associated capture-default and its
compound-statement odr-uses this
or a variable with automatic storage duration and the odr-used entity is not explicitly captured,
then the odr-used entity is said to be implicitly captured;
和
§5.1.2[expr.prim.lambda] / 12
§5.1.2 [expr.prim.lambda] / 12
如果 lambda-expression odr-使用 this
b $ b从其到达范围的存储持续时间,该实体将是由 lambda-expression
捕获的
。如果一个
一个实体,并且该实体没有在紧邻lambda表达式或函数的
中定义或捕获,该程序是
If a lambda-expression odr-uses this
or a variable with automatic
storage duration from its reaching scope, that entity shall be
captured by the lambda-expression
. If a lambda-expression captures
an entity and that entity is not defined or captured in the
immediately enclosing lambda expression or function, the program is
ill-formed.
ODR使用意味着在潜在评估的上下文中使用:
ODR use means use in potentially evaluated context:
§3.2[basic.def.odr] / 2
§3.2 [basic.def.odr] / 2
表达式可能被评估,除非它是未评估的
操作数或其子表达式。一个名为
潜在求值表达式的变量是 odr-used ,除非它是一个满足出现在常量表达式
中的要求的对象
,立即应用左值到右值转换
An expression is potentially evaluated unless it is an unevaluated operand or a subexpression thereof. A variable whose name appears as a potentially-evaluated expression is odr-used unless it is an object that satisfies the requirements for appearing in a constant expression and the lvalue-to-rvalue conversion is immediately applied
自 sizeof
isn' t, s
位于lambda表达式的到达范围,可以。返回 s
意味着评估它,这就是为什么它是不成形的。
Since sizeof
isn't, and s
is in reaching scope of the lambda expression, it is okay. Returning s
means evaluating it, though, and that's why it's ill-formed.
这篇关于sizeof可以应用于未捕获的变量上的lambda,或者这是一个编译器错误?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!