为什么将`uint8_t`赋值给`uint8_t`会给出转换警告?

时间:2015-09-14 21:51:01

标签: c type-conversion

为什么这段C代码:

#include <stdint.h>

uint8_t do_foo() {
  uint8_t int8;
  int8 = 0x80;
  int8 = int8 + (uint8_t) 1;
  return int8;
}

给这个编译器警告?

$ gcc --version
gcc (Debian 4.9.2-10) 4.9.2
$ gcc -c -Wall -Wextra -Wconversion test.c
test.c: In function ‘do_foo’:
test.c:6:10: warning: conversion to ‘uint8_t’ from ‘int’ may alter its value [-Wconversion]
   int8 = int8 + (uint8_t) 1;
          ^

据我所知,右边的表达式绝对是uint8_t类型,而不是int类型。

2 个答案:

答案 0 :(得分:6)

这是因为整数提升。

+的操作数小于int。因此,它们会被提升为int,并且会在int中进行添加。

对于int8的分配,结果必须转换回uint8_t,从而导致警告,因为该值可能不合适。

答案 1 :(得分:5)

为了简化编译器,最初定义的C仅允许对五种数字类型进行算术运算:intunsigned intlongunsigned long和{{1}因此意味着编译器只需要知道执行每个算术运算符的五种方法。此外,在二进制补码系统中,许多运算符可以对有符号和无符号整数类型使用相同的实现,因此只需要三个实现。尝试对上述任何一种类型或任何类型组合执行算术运算将导致“两个”操作数从上面的列表转换为相同的类型[左移和右移的右手操作符-shift类型独立于左侧。

虽然标准已经更改为将double添加到可以执行算术的类型列表中,但您的示例使用的类型float不在该列表中。通常,不在列表中的类型的值将转换为列表中的第一个类型,该类型可以包含相应类型的所有值,在您的情况下将为uint8_t。将两个操作数提升为类型int的添加并执行添加后,编译器会在尝试将结果分配回较小的类型时进行投诉。