uint16_t减法GCC编译错误
uint16_t subtraction GCC compilation error
我有以下程序
#include <stdio.h>
#include <stdlib.h>
#include <inttypes.h>
int main(void) {
uint16_t o = 100;
uint32_t i1 = 30;
uint32_t i2 = 20;
o = (uint16_t) (o - (i1 - i2)); /*Case A*/
o -= (uint16_t) (i1 - i2); /*Case B*/
(void)o;
return 0;
}
案例 A 编译没有错误。
情况B导致以下错误
[error: conversion to ‘uint16_t’ from ‘int’ may alter its value [-Werror=conversion]]
我使用的警告选项是:
-Werror -Werror=strict-prototypes -pedantic-errors -Wconversion -pedantic -Wall -Wextra -Wno-unused-function
我在 Ubuntu 15.04 64 位上使用 GCC 4.9.2。
为什么我在 案例 B 中出现此错误,但在 案例 A 中却没有?
PS:
我 运行 使用 clang 编译器的相同示例,两种情况都可以正常编译。
您的案例 B 相当于:
o = o - (uint16_t) (i1 - i2); /*Case B*/
结果是 int
,可能不适合 uint16_t
,因此,根据您的极端警告选项,它会产生警告(因此会产生错误,因为您将警告视为错误).
整数提升是个奇怪的东西。基本上,任何较小尺寸的所有整数值都会提升为 int
以便可以有效地对其进行操作,然后在存储时将其转换回较小的尺寸。这是 C 标准规定的。
所以,案例 A 真的是这样的:
o = (uint16_t) ((int)o - ((uint32_t)i1 - (uint32_t)i2));
(请注意,uint32_t
不适合 int
,因此无需推广。)
而且,案例 B 确实是这样的:
o = (int)o - (int)(uint16_t) ((uint32_t)i1 - (uint32_t)i2);
主要区别在于案例 A 具有显式转换,而案例 B 具有隐式转换。
来自 GCC 手册:
-Wconversion
Warn for implicit conversions that may alter a value. ....
因此,只有案例 B 会收到警告。
我有以下程序
#include <stdio.h>
#include <stdlib.h>
#include <inttypes.h>
int main(void) {
uint16_t o = 100;
uint32_t i1 = 30;
uint32_t i2 = 20;
o = (uint16_t) (o - (i1 - i2)); /*Case A*/
o -= (uint16_t) (i1 - i2); /*Case B*/
(void)o;
return 0;
}
案例 A 编译没有错误。
情况B导致以下错误
[error: conversion to ‘uint16_t’ from ‘int’ may alter its value [-Werror=conversion]]
我使用的警告选项是:
-Werror -Werror=strict-prototypes -pedantic-errors -Wconversion -pedantic -Wall -Wextra -Wno-unused-function
我在 Ubuntu 15.04 64 位上使用 GCC 4.9.2。
为什么我在 案例 B 中出现此错误,但在 案例 A 中却没有?
PS: 我 运行 使用 clang 编译器的相同示例,两种情况都可以正常编译。
您的案例 B 相当于:
o = o - (uint16_t) (i1 - i2); /*Case B*/
结果是 int
,可能不适合 uint16_t
,因此,根据您的极端警告选项,它会产生警告(因此会产生错误,因为您将警告视为错误).
整数提升是个奇怪的东西。基本上,任何较小尺寸的所有整数值都会提升为 int
以便可以有效地对其进行操作,然后在存储时将其转换回较小的尺寸。这是 C 标准规定的。
所以,案例 A 真的是这样的:
o = (uint16_t) ((int)o - ((uint32_t)i1 - (uint32_t)i2));
(请注意,uint32_t
不适合 int
,因此无需推广。)
而且,案例 B 确实是这样的:
o = (int)o - (int)(uint16_t) ((uint32_t)i1 - (uint32_t)i2);
主要区别在于案例 A 具有显式转换,而案例 B 具有隐式转换。
来自 GCC 手册:
-Wconversion
Warn for implicit conversions that may alter a value. ....
因此,只有案例 B 会收到警告。