GCC 6.2 中的 [[deprecated]] + __attribute__ ((visibility ("default")))

[[deprecated]] + __attribute__ ((visibility ("default"))) in GCC 6.2

[[deprecated]]__attribute__ ((visibility ("default"))) 属性与 -std=c++14 组合会产生错误(根据 expected identifier before ‘__attribute__’expected identifier before ‘[’ token 使用的顺序不同)。 单独使用它们不会产生错误。

c++11 样式属性 [[gnu::visibility("default")]] 适用于 类,但不适用于函数(代码可以编译,但会产生 -Wattributes 警告,并且当使用 -fvisibility=hidden).

构建

这是编译器中的错误(我使用 GCC 6.2 进行这些测试)还是 c++ 标准指定的错误?相同的代码 ([[deprecated]] __attribute__ ((visibility ("default")))) 使用 clang 按预期工作。

这是我用于组合所有可能性的测试代码,唯一产生所​​需结果(已弃用 + 默认可见性)的情况是 3 和 7,即使用旧样式属性的情况。

foo.h

#if defined(X_VERSION)
#  if (X_VERSION % 4) == 0        //  0   4   8  12
#    define DEPRECATED [[deprecated]]
#    define VISIBILITY [[gnu::visibility("default")]]
#  elif (X_VERSION % 4) == 1      //  1   5   9  13
#    define DEPRECATED [[deprecated]]
#    define VISIBILITY __attribute__ ((visibility ("default")))
#  elif (X_VERSION % 4) == 2      //  2   6  10  14
#    define DEPRECATED __attribute__((__deprecated__))
#    define VISIBILITY [[gnu::visibility("default")]]
#  elif (X_VERSION % 4) == 3      //  3   7  11  15
#    define DEPRECATED __attribute__((__deprecated__))
#    define VISIBILITY __attribute__ ((visibility ("default")))
#  else
#    error "Invalid X_VERSION"
#  endif

#  if (X_VERSION / 4) == 0        //  0   1   2   3
#    define DEPRECATED_API DEPRECATED VISIBILITY
#  elif (X_VERSION / 4) == 1      //  4   5   6   7
#    define DEPRECATED_API VISIBILITY DEPRECATED
#  elif (X_VERSION / 4) == 2      //  8   9  10  11
#    define DEPRECATED_API DEPRECATED
#  elif (X_VERSION / 4) == 3      // 12  13  14  15
#    define DEPRECATED_API VISIBILITY
#  else
#    error "Invalid X_VERSION"
#  endif
#else
#  error "X_VERSION not defined"
#endif

#if defined(DEPRECATED_API)
#  define XSTR(x) STR(x)
#  define STR(x) #x
#  pragma message "DEPRECATED_API = " XSTR(DEPRECATED_API)
#endif

class DEPRECATED_API foo
{
public:
    foo();
    virtual ~foo();
    void test();

    int a;
};

void DEPRECATED_API a_function();

foo.cpp

#include <foo.h>

foo::foo() {}
foo::~foo() {}
void foo::test() {}

void a_function() {}

CMakeLists.txt

cmake_minimum_required(VERSION 3.6)
project(test_lib)

set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fvisibility=hidden")
set(CMAKE_INCLUDE_CURRENT_DIR ON)


foreach(i RANGE 0 15)
  if(i LESS 10)
    set(target_name foo_v0${i})
  else()
    set(target_name foo_v${i})
  endif()
  add_library(${target_name} SHARED foo.cpp foo.h)
  target_compile_definitions(${target_name} PRIVATE X_VERSION=${i})
endforeach()

经过很多时间,我发现:

void [[deprecated]] [[gnu::visibility("default")]] a_function();

应该是:

 [[deprecated]] [[gnu::visibility("default")]] void a_function();

在这种情况下,版本 0 和 4 都按预期工作。