【问题标题】:Is there a difference between `__attribute__((some_attribute))` and `[[some_attribute]]`?`__attribute__((some_attribute))` 和 `[[some_attribute]]` 之间有区别吗?
【发布时间】:2018-02-01 18:37:22
【问题描述】:

我第一次遇到用方括号括起来的属性,我一直在做一些背景阅读:http://en.cppreference.com/w/cpp/language/attributes

至少对于 gcc,似乎允许使用多种技术:

__attribute__((some_attribute))

[[some_attribute]]

这是正确的吗?什么时候允许或不允许、首选或不首选一种技术?有什么不同?

看起来[[some_attribute]] 只允许从 C++11 开始,对吧?

【问题讨论】:

    标签: c++ c++11 attributes


    【解决方案1】:

    根据N4659

    10.6.1 属性语法和语义[dcl.attr.grammar]

    属性指定各种来源的附加信息 类型、变量、名称、块或翻译等结构 单位。

    attribute-specifier-seq:
        attribute-specifier-seqopt attribute-specifier
    
    attribute-specifier: 
        [ [ attribute-using-prefixopt attribute-list ] ]
        alignment-specifier
    

    所以,[[...]] 是一种标准化语法。

    相反,__attribute__ ((attribute-list))gcc extension 的语法:

    属性说明符的格式为__attribute__ ((attribute-list))。属性列表是一个可能为空的以逗号分隔的属性序列,其中每个属性是以下之一:

    ...

    由于 C++11 中引入了属性,并且您使用 gcc 并支持 C++11(或更高版本),因此两种类型的语法都可用给你。

    【讨论】:

    • 快速跟进:我可以将属性放在函数名之前或之后,例如属性[[noreturn]][[noreturn]] void foo();void foo() [[noreturn]];?
    • @GabrielStaples 第一个用法是正确的,第二个 - 不是。
    • 谢谢!我只花了大约 15 分钟左右检查了一下。当我使用g++ -Wall -std=c++11 no_return_practice.cpp 编译时,第一次使用它会编译并显示warning: ‘noreturn’ function does return [enabled by default]。当我运行它时,它会在此调用之后打印任何内容之前崩溃。我猜这是指定的行为——因为函数永远不会返回。所以这种用法有效。在第二次使用时,我收到一个编译器警告,指出 warning: attribute ignored [-Wattributes] void foo() [[noreturn]]...,并且程序正常运行,这意味着该属性不起作用。
    • @JesperJuhl,起初当我给 Edgar Rokjan 一个“正确答案”时,我感觉很糟糕,因为你的答案是第一个而且也是正确的。我不再觉得不好了。 :)
    【解决方案2】:

    [[foo]] 语法是在 C++11 中引入的。但在此之前许多编译器都有自己的语法(在某些情况下还支持一些非标准化的属性)。

    简而言之:[[foo]] 是标准的,应该可以在任何地方使用符合标准的编译器。其他语法是特定于编译器的。

    【讨论】:

    • C++11 标准格式的属性是命名空间的。所以 GCC 特定的 __attribute_((foo)) 等价于 [[gnu::foo]
    猜你喜欢
    • 2012-02-16
    • 1970-01-01
    • 1970-01-01
    • 2020-01-11
    • 2016-12-02
    • 2021-10-09
    • 2010-09-27
    • 2014-08-30
    • 2014-09-25
    相关资源
    最近更新 更多