Какое условие препроцессора я должен проверить, чтобы использовать __attribute __ ((const))? - PullRequest
1 голос
/ 20 октября 2019

Я получил фрагмент кода, который применяет __attribute__((const)) к некоторым функциям. Я бы предпочел не удалять его, когда его можно будет использовать, но, с другой стороны, я хочу быть более переносимым, поэтому - я хочу сказать

#if some condition here
#define ATTRIBUTE(an_attribute)  __attribute__((an_attribute))
#else
#define ATTRIBUTE(an_attribute)  
#endif

void foo(int x) ATTRIBUTE(const)

Каким должно быть условие?

Примечания:

  • Я знаю, что с C ++ 17 мы имеем это как правильный атрибут C ++;но я не могу предположить, что C ++ 17 используется. На самом деле, давайте предположим, что это не упрощает задачу.
  • Дополнительные баллы, если вы также можете ответить на вопрос для __attribute__((pure)).

Ответы [ 2 ]

2 голосов
/ 20 октября 2019

GCC предоставляет эти атрибуты в соответствии со стандартным синтаксисом атрибута , представленным в C ++ 11:

[[gnu::const]] // or [[gnu::pure]]
void foo(int x);

Начиная с C ++ 17, компиляторы обязаны игнорировать неизвестные атрибуты без неговызывая ошибку. На практике компиляторы часто предупреждают о неизвестных атрибутах (с возможностью отключить это предупреждение, конечно). Из того, что я видел в Compiler Explorer и из того, что я помню, компиляторы старше C ++ 17 также обычно предупреждают, когда они вообще понимают синтаксис. Основной компилятор, который я бы дополнительно протестировал, - это MSVC, но Compiler Explorer не слишком далеко заходит в версиях MSVC.

Если у вас уже есть макрос и вы не хотите изменять все его применения, вы можете работатьэто в:

#define ATTRIBUTE(an_attribute) [[gnu::an_attribute]]

Если это не разумное решение, я подозреваю, что вам, к сожалению, придется проверять конкретные компиляторы и версии в состоянии.

1 голос
/ 21 октября 2019

__attribute__ является расширением GNU. Его поддерживают только компиляторы и компиляторы GNU, которые утверждают, что являются GNU (например, Clang и ICC). Таким образом, вы можете сделать это:

#ifdef __GNUC__
# define ATTRIBUTE(x) __attribute__ (x)
# else
# define ATTRIBUTE(x)
#endif

const было введено в GCC 2.5 и pure во время разработки GCC 2.96, поэтому нет смысла тестировать отдельно для их поддержки: эти версии компилятора будутне может быть в состоянии скомпилировать текущий код C ++ в любом случае. (__attribute__ сам был представлен в GCC 2.0. Я думаю, что интерфейс C ++ всегда его поддерживал.)

...