C++ 编译器是否可以报告未知属性的错误?即使有范围?

C++ 编译器是否可以报告未知属性的错误?即使有范围?,c++,attributes,c++11,C++,Attributes,C++11,在N3291“7.6.1.(3/5)属性语法和语义[decl.attr.grammar]”中,我读到了关于属性如何在源代码中编写的内容 有条件地支持使用属性作用域标记,包括 实现定义的行为 及 对于本国际标准中未指定的属性标记,行为由实现定义 这是否意味着属性规范 [[ dllexport ]] [[ hiding ]] [[ unused ]] [[ vendor::attrib ]] 可能会被符合标准的编译器投诉?那么,它可以报告错误并停止编译吗 我希望编译器应该忽略它不知道如何处理的属性

在N3291“7.6.1.(3/5)属性语法和语义[decl.attr.grammar]”中,我读到了关于属性如何在源代码中编写的内容

有条件地支持使用属性作用域标记,包括 实现定义的行为

对于本国际标准中未指定的属性标记,行为由实现定义

这是否意味着属性规范

[[ dllexport ]]
[[ hiding ]]
[[ unused ]]
[[ vendor::attrib ]]
可能会被符合标准的编译器投诉?那么,它可以报告错误并停止编译吗

我希望编译器应该忽略它不知道如何处理的属性。好的,这可能很危险,因为属性中的键入可能会被忽略,例如
[[noretrun]]
[[carrys\u dependencie]]
:-)


但特别是名称空间在这里会有所帮助,对吗?当我在Microsoft编译器上编译
[[gcc::mips]]
时,应该能够忽略它,而不是拒绝它,对吗?

C++17添加了一条显式语句,即忽略实现无法识别的属性。在C++17之前,所有属性行为都是由实现定义的,因此实现可以做任何事情

属性规范的部分目的是使编译器制造商不再用特殊的语法和关键字混乱语言。给他们一个语法来指定这些东西。这是一种将编译器定义的字符串与特定对象或定义关联的方法

可能会被符合标准的编译器投诉

是的,尤其是这一个应该抱怨标准一致性编译器不支持有条件支持的行为(需要诊断消息)

然而,我不确定其他人。本标准还包含以下内容:

。。。如果某个属性特定于某个实体或 语句包含不允许应用于该语句的属性 实体或语句,程序格式不正确

我相信可以随意阅读,只有那些肯定违反规则的属性才会导致程序格式错误(即编译器不知道的属性不会),然而,我不太确定。无论如何,使用实现定义的行为不会使程序格式错误


目前,我相信新语法也会像这样工作。

因为C++17:所有实现未知的属性都会被忽略而不会导致错误。编译器只能发出警告


在C++17之前:编译器可以做任何事情。

…当然,除了带着错误消息停止之外(因为还没有人支持它);-)。好的,语法现在已经定义好了,但是编译器因为“我不知道属性名”而停止和因为“你奇怪的属性语法把我弄糊涂了”而停止有什么区别呢。我认为它被设计成一个可扩展的系统,但如果编译器停止在未知的东西上,这不是一个扩展的好地方。我猜我的假设是错误的?@towi您可以向您的编译器开发人员抱怨,它应该发出警告,而不是停止编译,因为语法已经定义,供应商可能会选择他喜欢的行为。定义语法的优点是,他可以确保匹配了一个属性,而不是一些语法错误。所以您说“实现定义的行为”大致翻译为“应该发出诊断,但继续编译”。但是为了让那些还不太完美的编译器更容易使用,它也被“允许”停止吗?@towi:不;“实现定义的行为”翻译成“编译器想做什么就做什么”。您可以争论编译器应该做什么,但规范没有说明编译器将做什么。因此,如果编译器想要停止,它就会停止。如果编译器想要发出警告,那也没关系。@towi:因为到目前为止还没有编译器支持这种语法,你应该告诉你的学生,如果他们希望自己的代码能够真正编译,就不要使用这种语法。在没有实际的实践之前,你不可能有一个“良好的实践规则”。因此,在多个编译器支持它之前,您所要做的就是规范。好吧,对于
[[vendor::attrib]
我现在看到了a)编译器可能不支持整个属性作用域(导致错误)和b)编译器支持作用域本身,但是
vendor
是一个未知的作用域。我不喜欢那种“有条件的支持”,但现在我明白了。如果允许编译器在未知的非作用域属性出现错误时停止,则此选项将保持打开状态。
gcc
只是警告,这正是我的观点:如果我依赖gcc实践,编译器会安全地忽略未知属性,该怎么办?我会在不知情的情况下编写不可移植的代码。糟糕,我认为。+1和-1符合“有条件支持”BS的标准。
[[ vendor::attrib ]]