【问题标题】:C++ attributes namespace?C++ 属性命名空间?
【发布时间】:2018-07-16 04:19:15
【问题描述】:

Cppreference 表示双括号内的 attribute-list [[ ]] 可以是标识符。

假设我的 C++ 程序中有一个名为 noreturn 的变量(因此它是变量的标识符)。它会干扰[[noreturn]] 属性的解释吗?我的想法是,如果 attribute-list 中的标识符与普通标识符共享相同的命名空间(在此示例中,它们都位于全局命名空间中),编译器可能会将其解释为一个标识符变量,则它不会将其识别为有效的 C++ 属性。

例子:

int noreturn = 1;
[[ noreturn ]] void f() {
     throw "error";
}

[[noreturn]]的用法在这里给出:https://en.cppreference.com/w/cpp/language/attributes/noreturn

更新:为了澄清,我知道在 C(不是 C++)中有 4 个“预定义”命名空间:标签、标签、结构/联合成员和普通标识符。但它是为 C (C11 6.2.3) 定义的,所以我想知道 C++11 是否添加了“属性”命名空间。根据公认的答案,在 C++ 中,规则的表达方式不同,但类比成立。

【问题讨论】:

  • 标准中没有任何内容将属性标识符链接到程序中定义的任何名称。这就是属性的重点。干扰其他名称的标识符称为保留字。属性名称不是保留字。
  • @n.m.我想你有点错过了我的观点..请查看更新。不过还是谢谢。

标签: c++ c++11


【解决方案1】:

属性属于不同的命名空间(与namespace 无关)。属性有一个命名空间。

标签也一样:

int l=2;
l: if (l<5) { l++; goto l; };

也是有效的(即使可能会让人难以理解)。

编译器可能会将其解释为变量的标识符,

不,不会的!

因此,在您的示例中,编译器不会将属性 noreturn 与变量 noreturn 混淆,就像在我上面的示例中一样,它不会将标签 l 与变量 l 混淆

参见 C++11 标准 n3337 §7.6.1 [dcl.attr.grammar] 进一步解释:

不会对包含在 属性令牌

当然为了可读性,我建议不要使用属性名称作为变量标识符(但这是一个提示,不是必需的)。

顺便说一句,您不想将预处理器 #define-d 符号与属性混合。

【讨论】:

  • 太好了,谢谢!我知道有 4 个“预定义”命名空间:标签、标签、结构/联合成员和普通标识符。但它是为 C (C11 6.2.3) 定义的,所以我想知道 C++11 是否添加了“属性”命名空间。根据你的回答,好像是这样。
  • C++有不同的规则(因为type和struct标签在同一个空格),但类比成立
  • > "不对包含在属性标记中的任何标识符执行名称查找 (3.4)。"不过有一个例外。它是“alignas”说明符,有时也被视为属性。对于“alignas”参数,您可以提供任何常量表达式,包括您定义为 const 的表达式。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-06-15
  • 2017-07-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-03-05
相关资源
最近更新 更多