Как остановить функции 'noreturn', отключив предупреждение '-Wreturn-type' с помощью G CC? - PullRequest
0 голосов
/ 26 мая 2020

При использовании макроса, который может расширяться до функции с атрибутом noreturn, есть ли способ остановить его от подавления -Wreturn-type?

Простой пример:

/* Defined in a separate header. */
#ifndef NDEBUG
#  define MY_ASSERT_MACRO(test) ((void)((test) ? 0 : abort()))
#else
#  define MY_ASSERT_MACRO(test) ((void)(0 ? 0 : (test)))
#endif

/* C source file. */
int function(enum MyEnum foo)
{
  switch (foo) {
     case A: return 1;
     case B: return 1;
  }
  MY_ASSERT_MACRO(0);

  /* <-- Missing return! This should always warn! */
}

Проблема с этим в сборках выпуска, это дает предупреждение -Wreturn-type, а в сборках отладки он вообще не дает предупреждения, так как abort имеет атрибут noreturn.

Я хотел бы получить предупреждение в обоих случаях, чтобы разработчики, использующие отладочные сборки, не нарушали выпускные сборки.

Есть ли (чистый *) способ остановить функцию прерывания от отключения предупреждения -Wreturn-type?


Не очень чистые способы:

  • Прерывание вызова с приведением для удаления атрибута noreturn:
    ((void (*)(void))(*(((void **)abort))))()
  • Сравните две вещи, которые теоретически могут быть одинаковыми:
    (((const void *)(abort) != (const void *)(stderr)) ? abort() : 0)

1 Ответ

1 голос
/ 27 мая 2020

Один из очевидных способов - просто отключить атрибут noreturn в abort путем компиляции с -D__noreturn__= -fno-builtin-abort. Вы также можете использовать настраиваемую оболочку:

#include <stdlib.h>

#include <signal.h>
void myabort() {
    raise(SIGABRT);
}

#define abort() myabort()

и скомпилировать с помощью -include myabort.h.

Но я предлагаю не делать этого и вместо этого выпускать сборки под -Wall -Werror в вашем CI и / или перехватчики precommit. Сборки релизов могут выдавать полезные предупреждения по многим причинам, например, потому что включены проверки _FORTIFY_SOURCE stati c или некоторые переменные, которые использовались в assert s, перестали использоваться. Таким образом, обход abort не решит проблему несогласованности отладки / выпуска.

...