sizeof可以应用于未捕获的变量上的lambda,或者这是一个编译器错误? [英] Can sizeof be applied inside a lambda on a variable that is not captured or is this a compiler bug?

查看:145
本文介绍了sizeof可以应用于未捕获的变量上的lambda,或者这是一个编译器错误?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是在这里找到的讨论的后续。

以下代码在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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆