Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Tags:

Combining the [[deprecated]] and the __attribute__ ((visibility ("default"))) attributes with -std=c++14 generate errors (different depending on the order used expected identifier before ‘__attribute__’ or expected identifier before ‘[’ token). Using them separately does not generate the errors.

The c++11 style attribute [[gnu::visibility("default")]] works for classes, but not for functions (the code compiles, but produces a -Wattributes warning and the symbol is left out when built with -fvisibility=hidden).

Is this a bug in the compiler (I used GCC 6.2 for these tests) or something specified by c++ standard? The same code ([[deprecated]] __attribute__ ((visibility ("default")))) works as expected using clang).

This is the code I used for my tests to combine all the possibilities, the only cases that produce the wanted result (deprecated + default visibility) are 3 and 7, i.e. the ones using the old style attributes.

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()
like image 653
Daniele E. Domenichelli Avatar asked Nov 30 '16 11:11

Daniele E. Domenichelli


People also ask

What is __ attribute __ (( visibility default?

Usually __attribute__((visibility("default"))) is used in combination with -fvisibility=hidden linker flag. The latter would make "hidden" the default visibility for all symbols of a shared library. Back to the original example from folly, class FOLLY_EXPORT OptionalEmptyException : public std::runtime_error { ... 12.

What is attribute visibility?

With the visibility type attributes, you can control whether and how a structure/union/class or an enumeration that is defined in one module can be referenced or used in other modules. Visibility attributes affect only types with external linkage.


1 Answers

After a lot of time, I found that:

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

should have been:

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

In this case, both version 0 and 4 work as expected.

like image 191
Daniele E. Domenichelli Avatar answered Oct 05 '22 09:10

Daniele E. Domenichelli