Why >>24 causes -Wconversion but >>23 doesn't?

↘锁芯ラ 提交于 2019-11-28 07:16:00

问题


Here is the code:

#include <stdint.h>

unsigned char f(uint32_t RGBA)
{
  return (RGBA>>24) & 0xFF;
}

When compiled with -Wconversion it causes "warning: conversion to ‘unsigned char’ from ‘uint32_t {aka unsigned int}’ may alter its value [-Wconversion]". If I lower the shift value to 23 or less the warning disappears.

I've looked through the C99 standard and I don't understand what happens here. If I remove the & operator then the warning is always emitted and that is probably good, as the result of the expression (after integer promotions) is larger than unsigned char. My only idea is that the warning is omitted for smaller shifts only because gcc is smart and sees that the result is 8-bit anyway, as the standard doesn't make this a special case. Am I right here?

And why does the shift value matter? Is that a GCC bug? Clang seems to not produce the warning for any shift values.

I'm using GCC 5.3.1 on a 64-bit Linux system.


回答1:


As mentioned by Shafik Yaghmour, this appears to be a bug in GCC:

GCC Bug 40752: -Wconversion generates false warnings for operands not larger than target type

It appears to have been present since version 4.4.0, first reported on 2009-07-14, and has 5 duplicates. Based on the comments in the bug report, there seems to be some debate on how to handle it.




回答2:


At least with gcc 5.4, 6.x and 7.x this issue has a simple work-around using a cast:

#include <stdint.h>

unsigned char f(uint32_t RGBA)
{
  return (unsigned char) ((RGBA>>24) & 0xFF);
}


来源:https://stackoverflow.com/questions/34775374/why-24-causes-wconversion-but-23-doesnt

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!