是否有属性告诉编译器忽略丢失的return语句?

时间:2019-06-26 08:48:02

标签: c

我不认为这是重复的,因为函数确实返回了幸福的道路。使用属性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 个答案:

答案 0 :(得分:3)

有两种方法可以消除警告:

  • 在C11中用适当的属性exit_program_with_epic_fail()标记_Noreturn函数,但是对于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 :(得分:1)

这似乎是一个纯粹的设计问题。

警告/错误“控制到达非void功能的末尾”不是问题,而只是指示您告诉实际问题在哪里。

您可以/应该将函数重写为

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;
}