看到一段挺有意思的 C++代码

2021-08-27 14:28:23 +08:00
 Hconk

这段代码 GCC 能编译通过。VS/Clang 会报错。

void f() {
  return  [ ] [ [ ] ] ( ) [ [ ] ] { [ [ , , , ] ] ; } ( ) ; 
}
3711 次点击
所在节点    C++
11 条回复
AoEiuV020
2021-08-27 14:41:43 +08:00
看不懂,猜是 ub,
GeruzoniAnsasu
2021-08-27 14:42:59 +08:00
这些[[]]都是 attributes 吗

原来有这么多能放的位置……
AoEiuV020
2021-08-27 14:44:20 +08:00
你哪个版本的 gcc? 我就没编译通过,
error: expected expression before ‘[’ token
error: void value not ignored as it ought to be
Hconk
2021-08-27 14:47:09 +08:00
@AoEiuV020 要用 g++,这是 C++代码。
kalluwa
2021-08-27 14:59:47 +08:00
嵌套 lambda?
GeruzoniAnsasu
2021-08-27 16:53:12 +08:00
仅 gcc 支持捕获列表后的 attribute,
void f(...){[](...)[[,,,]]{[[,,,]];}();}
上面这行去掉了捕获列表后的[[]],可以在其它编译器中通过
zzxxisme
2021-08-27 19:54:13 +08:00
尝试说一下我的理解。
1. 首先 [](){} 这样就是创建了一个 不接受任何输入,什么都不做,没有任何输出的 lambda
2. 然后 [](){} () 就是调用了一下上面说的 lambda

剩下的就是在加 attributes

3. lambda 声明返回值类型的地方是可以加 attribute 的,例如加一个[[noreturn]]就是 []() [[noreturn]] {}。而 [[ ]] 就是…加 0 个 attribute 。
4. 大括号里面的执行体里面也可以加 attribute,而且可以一次加多个,例如同时加 likely, fallthrough 就是 [[ likely, fallthrough ]]。而 [[ , , , ]] 就是…什么 attribute 也没有加。
5. 找了一份 C++ standard draft 看了一下 lambda expression 的定义,捕捉列表和参数列表应该是不可以加 attribute 的。我找的是这份 draft: https://eel.is/c++draft/expr.prim.lambda#nt:lambda-specifiers,可以看到 lambda-introducer (也就是捕捉列表)和 parameter-declaration-clause (就是 lambda-declarator 里面)之间是没说可以放东西的。
yyt6801
2021-08-27 20:40:09 +08:00
@zzxxisme 给大佬递烟
agagega
2021-08-28 12:30:02 +08:00
原来 attribute 里面还能放逗号啊
QBugHunter
2021-08-31 20:05:40 +08:00
请问是 fork 炸弹嘛。。
Hconk
2021-08-31 23:42:40 +08:00
@QBugHunter 不是,这段代码没有任何作用,只是用到了几个 C++特性,第一眼看上去不像是能编译的代码。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/798344

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX