首页 > 解决方案 > 为什么我需要强制转换两次才能使 -Werror=bad-function-cast 警告静音

问题描述

我有以下简单的代码:

#include <stdint.h>
#include <stdbool.h>

static uint8_t getStatus(void) 
{
    return 123u;
}

bool getError(void)
{

    bool error =  (bool)getStatus();
    return error;
}

我从 gcc 收到以下警告:

error: cast from function call of type 'uint8_t {aka unsigned char}' to non-matching type '_Bool' [-Werror=bad-function-cast]

来自 gcc 手册:

-Wbad-function-cast(仅限 C 和 Objective-C)每当函数调用被强制转换为不匹配的类型时发出警告。例如,如果 int malloc() 被强制转换为任何内容,则发出警告 *

所以有3个有趣的情况。gcc 只允许其中 2 个,但我看不出它们之间有任何潜在的区别。

bool error =  getStatus(); //THIS IS OK
return error;


bool error = (bool)getStatus(); //THIS IS BAD
return error;


bool error =  (bool)(uint8_t)getStatus(); //THIS IS OK!
return error;

所以我有3个问题:

  1. 为什么我不能将 getStatus() 的结果转换为 bool。
  2. 为什么我需要将结果从 getStatus 显式转换为 uint8_t,然后我可以转换为 bool。
  3. Werror=bad-function-cast 标志如何帮助我找到(或避免)问题,以及哪种问题?

标签: ccastinggcc-warning

解决方案


您提供的摘录中给出了该行为的一个原因:在 C89(但不在 C99、C11、C17 中)中,可以在不提供显式声明的情况下调用函数。然后例如,如果您没有#include <stdlib.h>,则隐含地认为具有声明int malloc()。如果你然后使用转换返回值的习惯malloc

char *foo = (char*)malloc(42);

那么你已经掩盖了一个严重的错误。不幸的是char *foo = (char*)malloc(42);,即使这样编译也很好,而char *foo = malloc(42);会导致打印诊断消息。

经验法则是永远不要转换函数调用的返回值。

请注意,到_Boolfrom的转换uint8_t不需要强制转换(显式转换),它可以通过隐式(无强制转换)转换来完成,因此任何强制转换的存在至少是一个风格错误。


推荐阅读