为什么 >>24 会导致 -Wconversion 但 >>23 不会?
Why >>24 causes -Wconversion but >>23 doesn't?
代码如下:
#include <stdint.h>
unsigned char f(uint32_t RGBA)
{
return (RGBA>>24) & 0xFF;
}
使用 -Wconversion
编译时会导致 "warning: conversion to ‘unsigned char’ from ‘uint32_t {aka unsigned int}’ may alter its value [-Wconversion]"。如果我将偏移值降低到 23 或更小,警告就会消失。
我查看了 C99 标准,但我不明白这里发生了什么。如果我删除 &
运算符,则始终会发出警告,这可能很好,因为表达式的结果(整数提升后)大于 unsigned char
。我唯一的想法是,仅因为 gcc 很聪明并且看到结果无论如何都是 8 位的,所以对于较小的班次省略了警告,因为标准并未将其作为特例。我在这儿吗?
为什么偏移值很重要?那是 GCC 错误吗? Clang 似乎不会对任何移位值产生警告。
我在 64 位 Linux 系统上使用 GCC 5.3.1。
如 Shafik Yaghmour 所述,这似乎是 GCC 中的错误:
GCC Bug 40752: -Wconversion generates false warnings for operands not larger than target type
它似乎从 4.4.0 版开始就存在,首次报告于 2009 年 7 月 14 日,并且有 5 个重复项。根据错误报告中的评论,似乎有一些关于如何处理它的争论。
至少对于 gcc
5.4
、6.x
和 7.x
这个问题有一个简单的解决方法:
#include <stdint.h>
unsigned char f(uint32_t RGBA)
{
return (unsigned char) ((RGBA>>24) & 0xFF);
}
代码如下:
#include <stdint.h>
unsigned char f(uint32_t RGBA)
{
return (RGBA>>24) & 0xFF;
}
使用 -Wconversion
编译时会导致 "warning: conversion to ‘unsigned char’ from ‘uint32_t {aka unsigned int}’ may alter its value [-Wconversion]"。如果我将偏移值降低到 23 或更小,警告就会消失。
我查看了 C99 标准,但我不明白这里发生了什么。如果我删除 &
运算符,则始终会发出警告,这可能很好,因为表达式的结果(整数提升后)大于 unsigned char
。我唯一的想法是,仅因为 gcc 很聪明并且看到结果无论如何都是 8 位的,所以对于较小的班次省略了警告,因为标准并未将其作为特例。我在这儿吗?
为什么偏移值很重要?那是 GCC 错误吗? Clang 似乎不会对任何移位值产生警告。
我在 64 位 Linux 系统上使用 GCC 5.3.1。
如 Shafik Yaghmour 所述,这似乎是 GCC 中的错误:
GCC Bug 40752: -Wconversion generates false warnings for operands not larger than target type
它似乎从 4.4.0 版开始就存在,首次报告于 2009 年 7 月 14 日,并且有 5 个重复项。根据错误报告中的评论,似乎有一些关于如何处理它的争论。
至少对于 gcc
5.4
、6.x
和 7.x
这个问题有一个简单的解决方法:
#include <stdint.h>
unsigned char f(uint32_t RGBA)
{
return (unsigned char) ((RGBA>>24) & 0xFF);
}