Wednesday, August 31, 2022

[SOLVED] How to use string variables in attributes

Issue

In GCC and Clang, we can pass an integer variable into an attribute.

constexpr auto SIZE = 16;

int a [[gnu::vector_size(SIZE)]];

This is particularly useful when we write templates.

template<size_t N>
struct Vec {
    int inner [[gnu::vector_size(N)]];
};

However, if the attribute requires a string, I cannot find a way to use a variable like that. Neither of these two approaches works.

constexpr const char* TARGET = "default";

[[gnu::target(TARGET)]] void foo() {}
constexpr const char TARGET[] = "default";

[[gnu::target(TARGET)]] void foo() {}

It there a way to achieve this?


Solution

Standard attributes that take strings, like [[depecrated("reason")]], take a string literal, and not a variable or other expressions. This is like the message in a static_assert declaration.

Looking at the gcc documentation for gcc-style __attribute__ specifiers https://gcc.gnu.org/onlinedocs/gcc/Attribute-Syntax.html#Attribute-Syntax:

A possibly empty comma-separated list of expressions. For example, format_arg attributes use this form with the list being a single integer constant expression, and alias attributes use this form with the list being a single string constant.

Where SIZE would be an integer constant expression, but "string constant" seems to mean string literal instead of constant expression of type const char[N] or const char*. It's probably the case that C++ [[attribute]] form would also require a string constant/literal, just like the standard attributes.


You can do this with a macro:

#define TARGET "default"
[[gnu::target(TARGET)]] void foo() {}

Or you can do this for a whole region of code with _Pragma("GCC target default"):

#pragma GCC push_options
#pragma GCC target "default"

void foo() {}

#pragma GCC pop_options

... Except this seems to be bugged with GCC where some part of the compiler does not recognise target("default"). And this pragma doesn't seem to work in general in C++ (with Clang or GCC in some simple tests), so this probably won't work. It may be fixed in the future though.

Either way, these wouldn't work with templates. There doesn't seem to be a technical reason why const char* type expressions shouldn't be allowed, only no one seems to have implemented it and it hasn't been standardised.



Answered By - Artyer
Answer Checked By - Robin (WPSolving Admin)