Reputation: 1063
The code is:
*(buf+2) |= (unsigned char)(mFlag & 0x7f);
buf
is unsigned char *
and mFlag
is unsigned char
I guess it is because the return value of operator|=
so that I get the warnings
warning: conversion to 'unsigned char' from 'int' may alter its value
How can I remove the warning? Is it due to operator|=
?
Upvotes: 3
Views: 5964
Reputation: 1
You can temporarily disable this warning as follows:
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wconversion"
*(buf+2) |= (mFlag & 0x7fu);
#pragma GCC diagnostic pop
Upvotes: 0
Reputation: 78973
In C all arithmetic (including &
) is done in types at least as wide as int
. So the result of your expression will always be int
or unsigned
depending on the type of your constant.
Since the constant 0x7f
is obviously within bounds for any of the character types the warning your compiler gives is in effect not really helpful, I would even consider it a bug.
The only thing that you can do about this is
*(buf+2) = (unsigned)*(buf+2) | 0x7FU;
That is to convert the value explicitly to the wider type. If this still gives you a warning for the assignenent use
*(buf+2) = (unsigned char)((unsigned)*(buf+2) | 0x7FU);
but then you should definitively think of upgrading your compiler or change the warning options that you use.
Upvotes: 5
Reputation: 41045
As @chris says, it's probably casting the result of the masking (and you get a warning when -Wconversion
flag is on)
I would use *(buf+2) = (unsigned char)((mFlag & 0x7f) | *(buf+2));
but if you insist on using |=
you can take advantage of compound literals (only for C99):
*(buf+2) |= (unsigned char){mFlag & 0x7f};
Upvotes: 0
Reputation: 70502
To remove the warning, you apparently need a temporary variable to hold the 0x7f
value.
unsigned char x = 0x7f;
*(buf+2) |= mFlag & x;
The problem seems to be that the compiler is treating any attempt to convert the literal to an unsigned char
via a cast results in the warning (further discussion indicates this is specific to the |=
operator, simple assignment does not seem to have a problem). However, initialization of a variable is allowed without warning.
Another workaround is to define an inline function to serve the same purpose as the cast. I made this function look similar to a C++ static_cast<>
:
template <typename T>
inline T static_conversion (T x) { return x; }
//...
*(buf+2) |= mFlag & static_conversion<unsigned char>(0x7f);
A C version (which also works for C++) would use a different inline function, since C doesn't have templates:
inline unsigned char to_unsigned_char (unsigned char x) { return x; }
/* ... */
*(buf+2) |= mFlag & to_unsigned_char(0x7f);
Upvotes: 0
Reputation: 157
Should be able to get rid if the warning by declaring the constant as unsigned
*(buf+2) |= (mFlag & 0x7fu);
Upvotes: 0