thundium
thundium

Reputation: 1063

warning: conversion to 'unsigned char' from 'int' may alter its value

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

Answers (5)

Pedro
Pedro

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

Jens Gustedt
Jens Gustedt

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

David Ranieri
David Ranieri

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

jxh
jxh

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

malaugh
malaugh

Reputation: 157

Should be able to get rid if the warning by declaring the constant as unsigned

*(buf+2) |= (mFlag & 0x7fu);

Upvotes: 0

Related Questions