C++ 为什么这个看起来无效的代码在g++;6.0?
考虑一下这个奇怪的程序:C++ 为什么这个看起来无效的代码在g++;6.0?,c++,g++,C++,G++,考虑一下这个奇怪的程序: int main() { int(*){} Is it C++14 or any other language? } (见现场演示&) 即使注释/缺失,即使我在g++6.0中使用-pedantic errors选项,代码也可以正常编译,没有任何错误和警告。对我来说,这似乎是一个编译器错误。这真的是编译器中的一个bug吗?在我可以测试的所有版本中,这看起来都是g++的bug/功能/问题。运行 int main() { int(*){} Is it C++
int main()
{
int(*){} Is it C++14 or any other language?
}
(见现场演示&)
即使注释
/
缺失,即使我在g++6.0中使用-pedantic errors
选项,代码也可以正常编译,没有任何错误和警告。对我来说,这似乎是一个编译器错误。这真的是编译器中的一个bug吗?在我可以测试的所有版本中,这看起来都是g++的bug/功能/问题。运行
int main()
{
int(*){} Is it C++14 or any other language?
}
对于不带编译标志的所有版本的g++,启用将提供以下程序集输出
main:
pushq %rbp
movq %rsp, %rbp
movl $0, %eax
leave
ret
我得到的唯一诊断是开玩笑,那就是
!!warning: extended initializer lists only available with -std=c++0x or -std=gnu++0x
Clang、ICC和MSV都未能编译此文件
编辑:
从评论中可以看出,gcc对此提出了一个错误。可以找到错误报告。我已使用
g++
version5.1.1
在我的Fedora虚拟机上运行该命令,并发现以下内容:
[user:~] 1 $ g++ -fdump-tree-original-raw tmp.cpp
tmp.cpp: In function ‘int main()’:
tmp.cpp:3:11: warning: extended initializer lists only available with -std=c++11 or -std=gnu++11
int(*){} Is it C++14 or any other language?
^
然而,它仍然设法编译。。。所以我得到了这个:
$ cat tmp.cpp.003t.original
;; Function int main() (null)
;; enabled by -tree-original
@1 return_expr type: @2 expr: @3
@2 void_type name: @4 algn: 8
@3 init_expr type: @5 op 0: @6 op 1: @7
@4 type_decl name: @8 type: @2 srcp: <built-in>:0
note: artificial
@5 integer_type name: @9 size: @10 algn: 32
prec: 32 sign: signed min : @11
max : @12
@6 result_decl type: @5 scpe: @13 srcp: tmp.cpp:1
note: artificial size: @10
algn: 32
@7 integer_cst type: @5 int: 0
@8 identifier_node strg: void lngt: 4
@9 type_decl name: @14 type: @5 srcp: <built-in>:0
note: artificial
@10 integer_cst type: @15 int: 32
@11 integer_cst type: @5 int: -2147483648
@12 integer_cst type: @5 int: 2147483647
@13 function_decl name: @16 type: @17 scpe: @18
srcp: tmp.cpp:1 lang: C
link: extern
@14 identifier_node strg: int lngt: 3
@15 integer_type name: @19 size: @20 algn: 128
prec: 128 sign: unsigned min : @21
max : @22
@16 identifier_node strg: main lngt: 4
@17 function_type size: @23 algn: 8 retn: @5
prms: @24
@18 translation_unit_decl
@19 identifier_node strg: bitsizetype lngt: 11
@20 integer_cst type: @15 int: 128
@21 integer_cst type: @15 int: 0
@22 integer_cst type: @15 int: -1
@23 integer_cst type: @15 int: 8
@24 tree_list valu: @2
$cat tmp.cpp.003t.原装
;; 函数int main()(空)
;; 由原始树启用
@1返回表达式类型:@2表达式:@3
@2无效类型名称:@4 algn:8
@3初始表达式类型:@5 op 0:@6 op 1:@7
@4类型名称:@8类型:@2 srcp::0
注:人工
@5整数类型名称:@9大小:@10 algn:32
prec:32符号:已签名最小值:@11
马克斯:@12
@6结果声明类型:@5 scpe:@13 srcp:tmp.cpp:1
注:人工尺寸:@10
algn:32
@7整数类型:@5整数:0
@8标识符\u节点strg:void lngt:4
@9类型名称:@14类型:@5 srcp::0
注:人工
@10整数类型:@15整数:32
@11整数类型:@5整数:-2147483648
@12整数类型:@5整数:2147483647
@13函数名称:@16类型:@17 scpe:@18
srcp:tmp.cpp:1lang:C
链接:extern
@14标识符\u节点strg:int lngt:3
@15整数类型名称:@19大小:@20 algn:128
prec:128符号:未签名的最小值:@21
马克斯:@22
@16标识符\u节点strg:主lngt:4
@17功能类型尺寸:@23 algn:8 retn:@5
prms:@24
@18翻译单位
@19标识符\u节点strg:bitsizetype lngt:11
@20整数类型:@15整数:128
@21整数类型:@15整数:0
@22整数类型:@15整数:-1
@23整数类型:@15整数:8
@24树列表值:@2
它太大了,无法放入评论中,但在确定发生了什么时应该是有用的。我仍在经历这些,但我只是把这些信息发布给其他人以供构建
它是这样可视化的。@KarolyHorvath:那么“为什么GCC 6在源代码中接受虚假的裸字?”?谁会搜索它?看这里相关:@πάνταῥεῖ 编译器单元测试对于这种愚蠢的、毫无意义的代码来说是一种实用的方法。这些毫无意义的代码在我的开发中经常以错误的形式出现,我希望我的编译器能够抓住我的许多错误。这段代码违反了我的预期,我想知道原因。提交一份错误报告:如果你还没有。据我所知,你的反汇编显示了一个简单的
返回0代码>表示提供的行。。。无论它是什么,基本上都是一个无操作。必须像某种声明一样对待…@LorenPechtel此代码在语法上无效,gcc应发出诊断并失败编译,不这样做是一个错误。我提交了@zwol,谢谢。我还没开始呢。我会将其添加到答案中。您是如何实现AST的可视化的?@HSchmale AST dump链接有一个或多个recipeDown投票者。请在您的推理中留下评论,以便改进此答案。