You are not logged in.
To make it simple, here's the code I have:
struct foo
{
unsigned int i : 2;
};
int main (void)
{
struct foo foo;
unsigned int i;
i = 2;
foo.i = (i > 3) ? 3 : i;
return 0;
}
When compiling with -Wconversion I get the following warning:
m.c: In function ‘main’:
m.c:13:25: warning: conversion to ‘unsigned char:2’ from ‘unsigned int’ may alter its value [-Wconversion]
foo.i = (i > 3) ? 3 : i;
^
If I get it right, it complains because there might not be enough space to store in foo.i whatever value is in i. However, unless I'm wrong (if so please correct me), it's easy enough (for us with human brains that is) to see the value will always fit.
So my question is: how can I "silence" this warning? I don't want to remove the -Wconversion for the whole project, not even for that file really, but I'd like not to have any warnings when compiling. Is it possible*?
(*) Well, other than going through each case manually, e.g: foo.i = (i == 0) ? 0 : (i == 1) ? 1 : (i == 2) ? 2 : 3;
Last edited by jjacky (2013-12-15 16:09:10)
Offline
You can use pragmas to ignore warnings.
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wconversion"
foo.i = (i > 3) ? 3 : i;
#pragma GCC diagnostic pop
I suspect it'd be easier/simpler/saner to just avoid the use of bitfields.
Offline
Replacing "i" with "i & 3" suppresses the warning for me, and I'd rather do that than use a GCC-specific pragma to disable it. But put a comment there to explain why it's there, so the next person to read the code doesn't "fix" it away.
FWIW, clang doesn't complain about it even with -Wconversion.
Offline
Replacing "i" with "i & 3" suppresses the warning for me, and I'd rather do that than use a GCC-specific pragma to disable it. But put a comment there to explain why it's there, so the next person to read the code doesn't "fix" it away.
#define MAX_FIELD_VALUE(s) ((1 << (s)) - 1)
// Use ">=" to avoid the redundant bitwise operation in the case of the max value.
#define SET_FIELD_VALUE(s, x) (\
(x >= MAX_FIELD_VALUE(s)) ? \
MAX_FIELD_VALUE(s) : \
MAX_FIELD_VALUE(s) & i \
)
#define FOO_FIELD_I_SIZE 2
#define SET_FOO_FIELD_I(x) SET_FIELD_VALUE(FOO_FIELD_I_SIZE, x)
// #define SET_2_BIT_FIELD(x) SET_FIELD_VALUE(2, x)
struct foo
{
unsigned int i : FOO_FIELD_I_SIZE;
};
int main (void)
{
struct foo foo;
unsigned int i;
i = 4;
foo.i = SET_FOO_FIELD_I(i);
return foo.i;
}
yo daw...
edit: corrected mistake in MAX_FIELD_VALUE macro
Last edited by Xyne (2013-12-17 07:29:27)
My Arch Linux Stuff • Forum Etiquette • Community Ethos - Arch is not for everyone
Offline
#define MAX_FIELD_VALUE(s) (s * 2 - 1) <elaborate preprocessing snipped>
Only for s==2.
#define MAX_FIELD_VALUE(s) ((1 << (s)) - 1)
There ought to be a better way to do saturating arithmetic in software. It's so easy with flip-flops and NAND gates. :-P
Last edited by Trent (2013-12-17 02:25:00)
Offline
Only for s==2.
#define MAX_FIELD_VALUE(s) ((1 << (s)) - 1)
Oops, nice catch. I actually started with that outside of the macro but ran into the negative conversion errors for the unsigned field. After testing some others things I didn't manage to come full circle back to shifting the bits.
There ought to be a better way to do saturating arithmetic in software. It's so easy with flip-flops and NAND gates. :-P
Indeed. A simple "make all of these 1" command would be nice. I'm guessing it can be done easily using assembly language.
My Arch Linux Stuff • Forum Etiquette • Community Ethos - Arch is not for everyone
Offline