Search code examples
c++attributesc++14deprecatedrawstring

How to pass raw string literals to [[deprecated(message)]] attribute?


I want to pass a raw string literals to [[deprecated(message)]] attribute as the message. The message is used again and again. So I want to avoid code repeat.

First, I tried to use static constexpr variable.

static constexpr auto str = R"(
Use this_func()
Description: ...
Parameter: ...
)";

[[deprecated(str)]] 
void test1() {
}

I got the error "deprecated message is not a string". It seems that static constexpr variable isn't accepted by [[deprecated(message)]].

I tried to define the row string literals as preprocessor macro.

#define STR R"(
Use this_func()
Description: ...
Parameter: ...
)"

[[deprecated(STR)]]
void test2() {
}

It works as I expected as follows on clang++ 8.0.0.

prog.cc:38:5: warning: 'test2' is deprecated: 
Use this_func()
Description: ...
Parameter: ...
 [-Wdeprecated-declarations]
    test2();
    ^

Demo: https://wandbox.org/permlink/gN4iOrul8Y0F76TZ

But g++ 9.2.0 outputs the compile error as follows:

prog.cc:19:13: error: unterminated raw string
   19 | #define STR R"(
      |             ^
prog.cc:23:2: warning: missing terminating " character
   23 | )"
      |  ^

https://wandbox.org/permlink/e62pQ2Dq9vTuG6Or

#define STR R"(  \
Use this_func()  \
Description: ... \
Parameter: ...   \
)"

If I add backslashes on the tail of each line, no compile error occurred but output message is different from I expected as follows:

prog.cc:38:11: warning: 'void test2()' is deprecated:   \\nUse this_func()  \\nDescription: ... \\nParameter: ...   \\n [-Wdeprecated-declarations]

I'm not sure which compiler works correctly.

Is there any way to pass the raw string literals variable/macro to [[deprecated]] attribute?


Solution

  • There is no such thing as a "raw string literal variable". There may be a variable which points to a string literal, but it is a variable, not the literal itself. The deprecated attribute does not take a C++ constant expression evaluating to a string. It takes a string literal: an actual token sequence.

    So the most you can do is use a macro to contain your string literal. Of course, macros and raw string literals don't play nice together, since the raw string is supposed to consume the entire text. So the \ characters will act as both continuations for the macro and be part of the string.