我正在为我的仿真器编写一些低级代码,其中涉及大量的16位和8位无符号整数。我启用了 -Wconversion
在我的项目中,所有的警告都被视为错误(-Werror
don't} want to see a warning for some particular case.
#include <cstdint>
int main ()
{
uint16_t a = 4;
uint16_t b = 6;
uint16_t c = a + b;
}
-std=c++17 -Wconversion -Werror
I ran into the same warning for doing a bit shift:
<source>: In function 'int main()':
<source>:7:20: error: conversion from 'int' to 'uint16_t' {aka 'short unsigned int'} may change value [-Werror=conversion]
7 | uint16_t c = a + b;
| ~~^~~
Clang output with warnings enabled:But the assembly listing shows no sign of the phantom GCC 10.1
promotion others are referring to in this thread. Only Clang
widths are used throughout:Clang 5.0.0
https:考虑这个代码片段。直到GCC 9.3与
作为编译标志,给出以下错误。
unsigned ints
同样的代码不会出现这个错误int
对于 Clang
(测试到 GCC
). GCC 10.1
到编译器资源管理器。GCC 10.1
所以我的问题如下。为什么?和
(直到9.3)会产生不同的结果?标准是否规定了对这个操作的限制,还是由编译器厂商来决定?是什么改变了
? 为什么这个错误没有出现在 ?
我正在为我的仿真器编写一些低级代码,其中涉及大量的16位和8位无符号整数。我在我的项目中启用了-Wconversion警告,所有的警告都被认为是错误(-Werror)。 我认为,两个无符号整数的加法不应该被隐式转换为一个int。还是我的假设有误?
这个的假设并没有错。无符号的int永远不会被隐含地转换为int.然而在你的系统中,uint16_t恰好是无符号的。
然而在你的系统中,uint16_t恰好是无符号的。
短暂int。假设无符号短ints没有被隐式转换为int是一个错误的假设。在大多数系统中,它们都被提升为int。
最近有一个关于
何以晋级是为了签到。
https:/stackoverflow.coma620423302079303。
它们并不一样。两者都会推广到int。一个只是没有警告转换。转换并不是错误的,所以没有要求发出诊断。unsigned int
unsigned short
还是由编译器厂商来决定?uint16_t
诊断信息是由编译器厂商决定的(,除非另有规定,否则当程序格式不良时需要诊断信息)。unsigned short
GCC 10.1中改变了什么?为什么GCC 10.1没有弹出这个错误?int
也许他们认为这个警告在这种情况下没有用,所以把它去掉了。+
int
unsigned int
没有增加两个
在您的代码中。事实上,你添加了两个 (int)4
,因为 (int)6
是一个类型定义,用于 (int)10
.c
整数推广规则规定,任何比整数类型窄的整数类型都要比
的操作数,它作为 c
晋升为
(不是 -Wconversion
如你所料)。)#pragma
所以涉及的步骤是
加到 -Wconversion
给予
你应该会发现,所有的编译器都会为
uint8_t left_shift(uint8_t a, uint8_t b) { return a << b; }
,代码的行为是有明确规定的。-Wconversion
准则的行为是有明确规定的。
<source>:10:53: warning: implicit conversion loses integer precision: 'int' to 'uint8_t' (aka 'unsigned char') [-Wimplicit-int-conversion]
uint8_t left_shift(uint8_t a, uint8_t b) { return a << b; }
~~~~~~ ~~^~~~
是比较有争议的。 正如这段代码就是一个很好的例子,它经常会对定义好的代码给出警告。 除了不使用标志,或者用某种方式包装假阳性(也许是通过 int
或一个函数调用)。)byte
有些人确实希望看到这段代码的警告,有些人不希望。 确切的情况是,在哪些情况下,警告会由
由于人们提交了错误报告,他们{do/godbolt.orgzeSVaQW]在gcc中不断变化。
left_shift(unsigned char, unsigned char):
push rbp
mov rbp, rsp
mov byte ptr [rbp - 1], dil
mov byte ptr [rbp - 2], sil
movzx eax, byte ptr [rbp - 1]
movzx ecx, byte ptr [rbp - 2]
shl eax, cl
movzx eax, al
pop rbp
ret