Return C 中运算符 == 的类型

Return types of operator == in C

任何运算符的 return 类型是什么? 如何判断?
它是否依赖于平台?

这个问题是在我执行 MISRA 代码合规性时突然出现的
需要像这样对 if 关键字的参数进行类型转换

if((bool_t)(cmd <= 1)){} 

安抚 14.4 MISRA 所需指南的 lint。 你能给我指点一些关于 operator return 类型的文档吗?
如果有人能找到
的 return 类型的文档 运营商请post在这里,因为这将对人们有很大帮助
下文提及。

使用if(1){...}执行{}中的代码

if(0){...} {} 中的代码不会被执行

return 类型是 int 和 equality/relational 运算符(==, <=, >=,...)在 C return 1 true0 false

Return types of operator == in C

... 结果的类型为 int。 ... C11dr 相等运算符 §6.5.9 3

What is the return type of any operator ?

有时取决于运算符和操作数

a*b --> result type could be `int`, `double`, etc.

其他,已修复

a==b --> result type is `int`.

How to determine it?

  1. 通过代码分析 - 您或静态分析器查看代码。

  2. 在运行时,使用_Generic()

下面处理了很多情况。

#define typenameX(X) _Generic((X), \
_Bool: "_Bool", \
signed char: "signed char", \
char: "char", \
unsigned char: "unsigned char", \
short: "short", \
unsigned short: "unsigned short", \
int: "int", \
unsigned: "unsigned", \
long: "long", \
unsigned long: "unsigned long", \
long long: "long long", \
unsigned long long: "unsigned long long", \
float: "float", \
double: "double", \
long double: "long double", \
_Complex float: "_Complex float", \
_Complex double: "_Complex double", \
_Complex long double: "_Complex long double", \
void *: "void *", \
char *: "char *", \
const char *: "const char *", \
default: "other" \
)

int main(void) {
  double a = 2.0;
  puts(typenameX(a));
  puts(typenameX(a==4.0));
  short b;
  puts(typenameX(b));
  puts(typenameX(b*1));
  puts(typenameX(sizeof(b)));
  double cmd;
  puts(typenameX(cmd <= 1));
}

输出

double
int
short
int
unsigned long
int

Is it platform dependent ?

对于cmd <= 1,C中的return类型是int - "platform independent".

((int)i) * 123456的结果类型是"platform dependent"。例如,它可以是 intlong

can you point me to some documentation regarding operator return type ?

if((bool_t)(cmd <= 1)){}的情况下,cmd <= 1的结果类型是int。 C11 §6.5.8 6. 在 C 中编译时不需要 bool_t。由于结果类型在其他语言中可能不同(或使用不兼容的 C 编译器),因此需要在多个语言中编译的代码语言可能会受益于演员表。

关于运算符 return 类型的最佳文档是(最新的)C 规范。


对 "required to typecast the parameters of the if keyword" 的担忧在神秘的情况下发挥作用。在 C 中比较的结果是不是其中之一。

C很好地定义了if(expression)的结果为"if the expression compares unequal to 0."。 C11dr §6.8.4.1 2

A 不兼容 编译器可能首先将浮点数或宽整数转换为 int 然后 然后 测试反对零。 if((bool_t)x) 解决了这个问题。

unsigned long long w = 0x800000000000u;
if (w) {

double x = 4294967296.0; // 0x1 0000 0000
if (x) {

double y = 0.123;
if (y) {

NaN 的处理有问题。 OTOH,C 没有很好地定义 NaN 与 0 的比较方式。IEEE 758 很好地定义了它,许多 C 实现都遵循这一点。在这种情况下,我认为转换为 (bool_t) 没有帮助,因为它同样会丢失 NaN。

double z = 0.0/0.0; // z is NaN;
if (z) {

if (!z) {

在早期的 C++ 中,也没有布尔值。用户定义的对象(但不是 doublefloat、指针)已针对 if() 转换为 int。如果非零值转换为 int 0,则算术 class(例如影响 256 整数)会出现问题。使用 !! 解决了这个问题。

myint256 a = foo();
if (!!a) {

注意:如果编译器没有真正的布尔类型,那么 (bool_t) 可能是某种整数类型,肯定会造成代码错误,就像上面那样。

What is the return type of any operator ? How to determine it?

这取决于运营商。通常,结果与提升的操作数具有相同的类型。 "logical" 运算符(比较运算符和 && || !)的行为不同,因为它们 return int,出于历史原因,因为在过去,C 没有 bool类型。

MISRA-C:2012 规则 14.4 要求 if 语句的内容应为 "essentially boolean"。其含义在MISRA文档中有详细解释,但大致意思是你应该假装C内置了一个bool类型,并假装上面提到的运算符的结果实际上是bool。这会提高可读性,并显着提高静态分析期间的类型安全性。

然而

if((bool_t)(cmd <= 1)){} 是胡说八道,表达式 cmd <= 1 的 return 类型已经 本质上是布尔值 。不需要演员表。如果 Lint 给你警告,那么 Lint 中有错误,提交错误报告。

MISRA 编译代码如下所示:

if(cmd <= 1)

if(cmd <= 1u)

can you point me to some documentation regarding operator return type ?

C 标准的第 6.5 章。这是视具体情况而定。大致:

  • 用于访问元素的运算符(例如[]、一元*、一元&->)returns 的类型元素.
  • 赋值运算符return左操作数的类型。
  • 关系运算符、相等运算符、! && ||运算符returnint取值10,你可以把它们看作布尔类型。
  • 移位运算符return提升后的左操作数的类型。
  • 所有其他运算符 return promoted/balanced 操作数的类型(如果适用)。