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 都按预期工作。
将 [[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 都按预期工作。