不同返回类型的gcc警告

不同返回类型的gcc警告,c,gcc,C,Gcc,我已经用C编写了一个库,现在它将用于嵌入式处理器板。我需要减少内存足迹,因此将一些函数的返回类型从int改为char(仅用于标记错误) 更改返回类型但不更改返回的变量不会产生警告。在gcc中是否有某种方法设置此项,因为我希望确保捕获了所有实例 char processSomething (SomeType *something) { int result = 0; ... do stuff ... return result; /* no warning */ } 谢谢

我已经用C编写了一个库,现在它将用于嵌入式处理器板。我需要减少内存足迹,因此将一些函数的返回类型从int改为char(仅用于标记错误)

更改返回类型但不更改返回的变量不会产生警告。在gcc中是否有某种方法设置此项,因为我希望确保捕获了所有实例

char processSomething (SomeType *something)
{
  int result = 0;
  ...
  do stuff
  ...

  return result; /* no warning */
}
谢谢

6月19日: 我添加了-Wconversion,它突出显示了一些有趣的东西。这有两个问题。我的一个函数是采用两个字符的十六进制字符串,并使用

字符十进制

decimal = hexstring [0] - '0' << 4 + hexstring [1] - '0'; // for 0 to 9
decimal=hexstring[0]-“0”在我的简单测试用例()中,在这种特定的情况下,应该会给出您想要的警告:

我收到以下警告:

警告:从“int”转换为“char”可能会改变其值[-Wconversion]


这是一个非常糟糕的主意:
char
在大多数嵌入式系统中是一个特定的大小(通常为1字节,因此它实际上是一个
无符号char
),如果您最终以某种方式设置
int result=256
,它将溢出并返回0。你的错误变成了成功。粗鲁无礼(希望如此)。更糟糕的是,可能会用你的嵌入式设备杀人

我知道你在试图解决这个问题,但即使只是返回幻数也是危险的

相反,请声明一个属于错误的枚举类型。它将在一定程度上为您提供类型安全性,并自动为您的函数创建正确的返回大小

typedef enum status {
    STATUS_OK = 0,
    STATUS_ERR1,
    STATUS_ERR2,
// ... etc ...
} status_t;

status_t processSomething (SomeType *something)
{
  status_t result = STATUS_OK;
  ...
  do stuff
  ...

  return result;
}
这更安全,编译器只会为您的返回分配1个字节,直到您有太多的返回,只有这样,它才会使返回更大。 取自当前的C标准(C99):

6.7.2.2枚举说明符 [...] 约束条件 定义枚举常量值的表达式应为具有可表示值的整型常量表达式 作为一个int。 [...] 每个枚举类型应与char、有符号整数类型或无符号整数类型兼容。类型的选择很简单 定义了实现,但应能够代表 枚举的所有成员的值


函数返回值将在寄存器中。您没有说明是哪个处理器,您的问题只有在8位时才有意义。请注意,
char
可以是有符号的,也可以是无符号的!最好明确说明这一点。最好使用
stdint.h
中的
uint8\u t
int8\u t
,特别是对于嵌入式设备,这是推荐的方法。我怀疑这样做是否有助于减少内存使用。如果只是返回
true
/
false
,请使用
bool
stdbool.h
-没有人会使用像
\u Bool
这样的重新解析的名称)。正如其他人已经指出的那样:只有当目标为8位时,这才会节省内存空间。对于任何较大的值,
int
很可能会与
char
char
被标准定义为无符号或有符号。它甚至可以在相同体系结构的编译器之间更改,除非它们使用相同的ABI/PCS.
enum
OTOH将至少是一个
int
。这不会保存任何内容。(但是,如果是错误代码,最好将返回值作为enum)。enum不是“至少一个int”,而是“最多一个int”,至少这是我在这里的理解:我更喜欢作为参考。请注意,p4只涉及_兼容性。这就是为什么我会返回
(u)int8_t
,但使用枚举标签。好的,从C99中,6.7.2.2p4说每个枚举类型应与char、有符号整数类型或无符号整数类型兼容。类型的选择由实现定义,108),但应能够表示枚举的所有成员的值。[…]脚注108添加了一个实现,该实现可能会延迟选择哪种整数类型,直到看到所有枚举常量。如果返回uint8_t而不是enum,则很快就会出现溢出风险。256个错误代码是相当合理的。。有趣,是的,你似乎是对的,我应该仔细阅读。然而,这仍然不能保证char
char
,但可能允许它。这就是我批评枚举的主要观点。如果可以显式地指定它的类型,那就容易多了。。
typedef enum status {
    STATUS_OK = 0,
    STATUS_ERR1,
    STATUS_ERR2,
// ... etc ...
} status_t;

status_t processSomething (SomeType *something)
{
  status_t result = STATUS_OK;
  ...
  do stuff
  ...

  return result;
}