[[已弃用]] + __attribute__ ((visibility ("default"))) 在 GCC 6.2 中

Dan*_*lli 5 c++ gcc visibility deprecated c++14

将[[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();
Run Code Online (Sandbox Code Playgroud)

foo.cpp

#include <foo.h>

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

void a_function() {}
Run Code Online (Sandbox Code Playgroud)

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()
Run Code Online (Sandbox Code Playgroud)

Dan*_*lli 5

经过很多时间,我发现:

void [[deprecated]] [[gnu::visibility("default")]] a_function();
Run Code Online (Sandbox Code Playgroud)

本来应该:

 [[deprecated]] [[gnu::visibility("default")]] void a_function();
Run Code Online (Sandbox Code Playgroud)

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