Есть ли атрибут, который указывает компилятору игнорировать пропущенную инструкцию возврата? - PullRequest
5 голосов
/ 26 июня 2019

Я не верю, что это дубликат, потому что функция возвращает в счастливом пути. Использование атрибута no-return позволяет компилятору оптимизировать в предположении, что функция никогда не вернется, что здесь не так.

Я получил код C, который либо возвращает указатель, либо вызывает другую функцию для выхода из программы. Это в операторе if, поэтому он либо возвращает результат, либо завершает работу. Поскольку функция возвращает void *, компилятор предупреждает, что, возможно, функция не будет возвращать значение (что, конечно, верно):

error: control reaches end of non-void function [-Werror=return-type]

Я могу обойти это, просто добавив return *temp; в конец функции, но я хотел бы прояснить свое намерение, имея что-то вроде атрибута неиспользуемой переменной:

__attribute__((__unused__))

Таким образом, я могу оставить -Wall включенным и не добавлять ненужный или, возможно, сбивающий с толку код.

Я также был бы готов переписать код, если есть лучший способ выразить это намерение.

Код выглядит примерно так:

void *get_memory() {
    void *temp = malloc(100);
    if (temp) {
        // do some setup work
        return temp;
    } else {
        exit_program_with_epic_fail();
    }
    // Compiler warns if the following line isn't present
    return temp;
}

Ответы [ 2 ]

3 голосов
/ 26 июня 2019

Есть 2 способа избавиться от предупреждения:

  • помечает функцию exit_program_with_epic_fail() соответствующим атрибутом _Noreturn в C11, но не существует переносимого способа сделать это с компиляторами до C11. Многие компиляторы поддерживают __attribute__((noreturn)), в частности gcc , clang и tinycc , но это расширение, специфичное для компилятора.
  • реорганизовать код, чтобы компилятор увидел, что функция всегда возвращает.

Вот модифицированная версия:

void *get_memory(void) {
    void *temp = malloc(100);
    if (!temp) {
        exit_program_with_epic_fail();
    }
    // do some setup work
    return temp;
}
1 голос
/ 26 июня 2019

Кажется, это чисто дизайнерская проблема.

Предупреждение / ошибка "управление достигает конца не пустой функции" - это не проблема, это скорее просто индикатор, указывающий, где находится настоящая проблема.

Вы можете / должныпросто переписать функцию как

void *get_memory (void) 
{
  void *temp = malloc(100);
  if(temp != NULL)
  {
    // do stuff
  }

  return temp;
}

и оставить обработку ошибок вызывающей стороне.Потому что это не работа функции выделения для завершения приложения - это плохой дизайн.

Альтернативная версия с подробной обработкой ошибок:

typedef enum
{
  OK,
  ERR_OUTOFMEMORY,
  ...
} err_t;

err_t get_memory (void** mem) 
{
  *mem = malloc(100);
  if(*mem == NULL)
  {
    return ERR_OUTOFMEMORY;
  }

  // do stuff

  return OK;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...