C++属性命名空间?

4

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++中规则表达方式不同,但类比仍然适用。


1
标准链接中没有将任何名称与程序中定义的名称进行标识。这就是属性的作用。干扰其他名称的标识符称为保留字。属性名称不是保留字。 - n. m.
@n.m. 我觉得你稍微误解了我的意思,请看更新。不过还是谢谢。 - Leedehai
1个回答

3

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

标签也是如此:

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

这也是有效的(尽管可能阅读起来令人困惑)。

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

不会出现这种情况!

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

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

任何属性标记中包含的标识符都不进行名称查找(3.4)。

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

顺便说一下,您不想将预处理器#define符号与属性混合使用。


太好了,谢谢!我知道有4个“预定义”命名空间:用于标签、用于标记、用于结构/联合成员和用于普通标识符。但它是为C定义的(C11 6.2.3),所以我想知道C++11是否已经添加了一个“属性”命名空间。根据你的回答,似乎是这样的情况。 - Leedehai
1
C++有不同的规则(因为类型和“struct”标签在同一空间中),但类比仍然成立。 - Basile Starynkevitch
“在属性标记中包含的任何标识符上都不执行无名称查找(3.4)。” 但是有一个例外,那就是“alignas”说明符,有时也被视为属性。对于“alignas”参数,您可以提供任何常量表达式,包括您定义为const的表达式。 - Stepan Dyatkovskiy

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接