c - 为什么我需要强制转换两次才能使 -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个问题:
- 为什么我不能将 getStatus() 的结果转换为 bool。
- 为什么我需要将结果从 getStatus 显式转换为 uint8_t,然后我可以转换为 bool。
- Werror=bad-function-cast 标志如何帮助我找到(或避免)问题,以及哪种问题?
解决方案
您提供的摘录中给出了该行为的一个原因:在 C89(但不在 C99、C11、C17 中)中,可以在不提供显式声明的情况下调用函数。然后例如,如果您没有#include <stdlib.h>
,则隐含地认为具有声明int malloc()
。如果你然后使用转换返回值的坏习惯malloc
:
char *foo = (char*)malloc(42);
那么你已经掩盖了一个严重的错误。不幸的是char *foo = (char*)malloc(42);
,即使这样编译也很好,而char *foo = malloc(42);
会导致打印诊断消息。
经验法则是永远不要转换函数调用的返回值。
请注意,到_Bool
from的转换uint8_t
不需要强制转换(显式转换),它可以通过隐式(无强制转换)转换来完成,因此任何强制转换的存在至少是一个风格错误。
推荐阅读
- php - 调试本地 Symfony 服务器并非在所有地方都有效
- javascript - 谷歌地图 javascript api 更新标记
- python - Element.text 数据丢失
- extjs - 如何在 Ext.Component ExtJS 中显示存储中的数据
- regex - regexp tcl 搜索变量
- python - 我的代码实际上并没有插入数据库
- grails - Grails 日期选择器丢失设置
- elasticsearch - 在字段中创建弹性搜索索引时具有 mapper_parsing_exception
- jquery - 画廊中的下一个和上一个按钮
- npm - 通过插入而不是附加将参数传递给 npm 脚本命令