GCC warnings for comma operator

W

W Karas

Recently I wrote a macro to set a bit field at an arbitrary location in an array of some unsigned integral type. (Can't show it because it's proprietary.) The bit field is specified as a bit offset from the start of the array, and the number of bits of width. Probably a mistake, but I decided it would (somehow) be more aesthetic if the macro expanded to an expression with side effects (and useless value) rather than a (compound) statement. The expanded macro has multiple instances of this pattern:

yada-yada , (exprA ? exprB : 0), yada-yada

where exprB has side effects. GCC seems to have no complaints as long as exprB evaluates to a constant value known at compile time. But if exprB hasa variable in it, and exprA is false, GCC gives a "value not used in commaexpression" warning (using -Wall) or something like that. The -Wno-unused-value option eliminates this warning. I would like to ask 2 questions.

1) What are some problems I might miss by using -Wno-unused-value ? I thought it might disable the warning for unused variables, but that is separate and covered by -Wunused-variables.

2) Is there a more targeted way to eliminate this spurious warning? I'd hate to have to put pragmas every place I invoked the macro.
 
G

glen herrmannsfeldt

(snip)
yada-yada , (exprA ? exprB : 0), yada-yada
where exprB has side effects. GCC seems to have no complaints as
long as exprB evaluates to a constant value known at compile time.
But if exprB has a variable in it, and exprA is false, GCC gives
a "value not used in comma expression" warning (using -Wall) or
something like that. The -Wno-unused-value option eliminates
this warning. I would like to ask 2 questions.
1) What are some problems I might miss by using -Wno-unused-value ?
I thought it might disable the warning for unused variables,
but that is separate and covered by -Wunused-variables.

I believe no-unused-value is related to legal but useless expressions
like:

x+2;

I suppose mostly useful for typos, such as when you meant:

x=2;

Seems to me that you have to evaluate the cost (looking through
all the false hits) of warnings against the value (finding something
that would be very difficult otherwise).

I believe that no-unused-value specifically excludes function
calls, which are assumed to have side effects. You might try

sqrt(2.2);

to test it.
2) Is there a more targeted way to eliminate this spurious warning?
I'd hate to have to put pragmas every place I invoked the macro.

Personally, I have rarely found use for it. In the EMS (Expanded
memory) days, I did have macros that expanded to the appropriate
EMS calls in some cases, or to a constant expression in others.

I remember warnings, and that was from before gcc.

-- glen
 
W

W Karas

Recently I wrote a macro to set a bit field at an arbitrary location in an array of some unsigned integral type. (Can't show it because it's proprietary.) The bit field is specified as a bit offset from the start of the array, and the number of bits of width. Probably a mistake, but I decided it would (somehow) be more aesthetic if the macro expanded to an expression with side effects (and useless value) rather than a (compound) statement. The expanded macro has multiple instances of this pattern:



yada-yada , (exprA ? exprB : 0), yada-yada



where exprB has side effects. GCC seems to have no complaints as long asexprB evaluates to a constant value known at compile time. But if exprB has a variable in it, and exprA is false, GCC gives a "value not used in comma expression" warning (using -Wall) or something like that. The -Wno-unused-value option eliminates this warning. I would like to ask 2 questions.



1) What are some problems I might miss by using -Wno-unused-value ? I thought it might disable the warning for unused variables, but that is separate and covered by -Wunused-variables.



2) Is there a more targeted way to eliminate this spurious warning? I'dhate to have to put pragmas every place I invoked the macro.


Guess I'll do this:

#if defined(__GNUC__) || defined(__cplusplus__)

#define NOTHING(TYPE) ((TYPE) nothing_())

static inline int nothing_(void) { return(0); }

#else

#define NOTHING(TYPE) ((TYPE) 0)

#endif

and replace the zero with an invocation of the NOTHING macro.
 
I

Ian Collins

W said:
Recently I wrote a macro to set a bit field at an arbitrary location
in an array of some unsigned integral type. (Can't show it because
it's proprietary.) The bit field is specified as a bit offset from
the start of the array, and the number of bits of width. Probably a
mistake, but I decided it would (somehow) be more aesthetic if the
macro expanded to an expression with side effects (and useless value)
rather than a (compound) statement. The expanded macro has multiple
instances of this pattern:

yada-yada , (exprA ? exprB : 0), yada-yada

I guess the obvious question is why use a macro at all? This looks like
an obfuscated code competition entry!
 
W

W Karas

I guess the obvious question is why use a macro at all? This looks like

an obfuscated code competition entry!

If performance matters, and most bit field accesses involve a constant offset and width, the macros are superior to functions. They are also configurable to work with address spaces other than primary memory that may use a word size and byte order different from the CPU executing the C code.
 
J

James Kuyper

On 04/10/2013 09:48 PM, W Karas wrote:
....
If performance matters, and most bit field accesses involve a constant offset and width, the macros are superior to functions. They are also configurable to work with address spaces other than primary memory that may use a word size and byte order different from the CPU executing the C code.

A decent compiler can often give an inline function the same performance
benefit as a macro, and the function is often far easier to write.
 
I

Ian Collins

Please fix your quoting!
If performance matters, and most bit field accesses involve a
constant offset and width, the macros are superior to functions.

Very unlikely with current optimising compilers.
They are also configurable to work with address spaces other than
primary memory that may use a word size and byte order different from
the CPU executing the C code.

So can a function.
 
N

Noob

W said:
Recently I wrote a macro to set a bit field at an arbitrary location
in an array of some unsigned integral type. (Can't show it because
it's proprietary.) The bit field is specified as a bit offset from
the start of the array, and the number of bits of width. Probably a
mistake, but I decided it would (somehow) be more aesthetic if the
macro expanded to an expression with side effects (and useless value)
rather than a (compound) statement. The expanded macro has multiple
instances of this pattern:

yada-yada , (exprA ? exprB : 0), yada-yada

Please give more details about the macro's specs.

If I understand your description correctly, the inputs are:

1) an unsigned {char,short,int,long,long long} array
2) an offset, in bits
3) the number of bits affected

Question #1
When you say you "set" several bits, does that mean they all
take the value "1" or do you use "set" in the general sense,
meaning there's a 4th parameter, the value to set the
specified bits to? (In the second case, if the value is 0,
then the macro would actually clear the bits.)

Question #2
Can the affected bits span multiple cells?
For example, suppose we have
unsigned char arr[128];
and we want to set bits 5 to 47 in one go
Does your macro allow that?

Question #3
Are there upper bounds on the offset and the width?

Question #4
Do you test for out-of-bounds access?
Suppose we have
unsigned char arr[2]
and the macro is used to set bits 5 to 47
what happens then?

Regards.
 
J

James Kuyper

Recently I wrote a macro to set a bit field at an arbitrary location
in an array of some unsigned integral type. (Can't show it because
it's proprietary.) The bit field is specified as a bit offset from
the start of the array, and the number of bits of width. Probably a
mistake, but I decided it would (somehow) be more aesthetic if the
macro expanded to an expression with side effects (and useless value)
rather than a (compound) statement. ...

I agree - that was probably a mistake.
... The expanded macro has multiple
instances of this pattern:

yada-yada , (exprA ? exprB : 0), yada-yada

Insofar as the C grammar can be described in terms of precedence, the
comma operator has absolutely the lowest precedence, so the parentheses
are unnecessary. They don't hurt anything, and if they make it easier
for you to understand what you're writing, go ahead, but I wouldn't
bother with them.
where exprB has side effects. GCC seems to have no complaints as
long as exprB evaluates to a constant value known at compile time.
But if exprB has a variable in it, and exprA is false, GCC gives a
"value not used in comma expression" warning (using -Wall) or
something like that.

The sole reason you have the 0 is that you've
chosen to use the ?: operator, and the sole reason you made that choice
is because you want evaluation of exprB to depend upon whether or not
exprA is non-zero. There's a simpler, more direct way to do that, which
doesn't involve a 0: (exprA && exprB). I've no idea whether that will
affect the warning message you're getting, but it's worth a try.
 
W

W Karas

I agree - that was probably a mistake.

Then again, when there are 'if' statements within macros, and the condition of the 'if' is a constant that can be evaluated at compile time, you can get "unreachable code" warnings.
 
J

James Kuyper

Then again, when there are 'if' statements within macros, and the condition of the 'if' is a constant that can be evaluated at compile time, you can get "unreachable code" warnings.

Again, that's something you could probably avoid using an inline
function rather than a macro. Depending upon the details of the macro
(which you haven't given us), if it were converted into an inline
function, the compiler might not even put "constant expression" together
with "if()" until after it's inlined the code, at which point you're
unlikely to get that particular warning.
 
W

W Karas

Again, that's something you could probably avoid using an inline

function rather than a macro. Depending upon the details of the macro

(which you haven't given us), if it were converted into an inline

function, the compiler might not even put "constant expression" together

with "if()" until after it's inlined the code, at which point you're

unlikely to get that particular warning.

Can't show the actual code, it's proprietary work stuff.

With the compilers we use (GCC, Green Hills) I've been very disappointed with how they handle nested inline functions.
 
J

Jorgen Grahn

.
With the compilers we use (GCC, Green Hills) I've been very
disappointed with how they handle nested inline functions.

Recent or very old gcc? I'd expect a recent one to be good at
inlining, because it's a C feature that's used a lot these days, and
because it's even /more/ used in the C++ half of gcc.

I'm also asking because I know from experience that in the embedded
space you often find yourself locked to outdated tools.

Of course I'm biased: I use gcc a lot, and while I do it on "embedded"
systems, these systems have powerful CPUs belonging to well-known and
well-supported families.

/Jorgen
 
T

Tim Rentsch

W Karas said:
Recently I wrote a macro to set a bit field at an arbitrary
location in an array of some unsigned integral type. (Can't show
it because it's proprietary.) The bit field is specified as a bit
offset from the start of the array, and the number of bits of
width. Probably a mistake, but I decided it would (somehow) be
more aesthetic if the macro expanded to an expression with side
effects (and useless value) rather than a (compound) statement.
The expanded macro has multiple instances of this pattern:

yada-yada , (exprA ? exprB : 0), yada-yada

where exprB has side effects. GCC seems to have no complaints as
long as exprB evaluates to a constant value known at compile time.
But if exprB has a variable in it, and exprA is false, GCC gives a
"value not used in comma expression" warning (using -Wall) or
something like that. The -Wno-unused-value option eliminates this
warning. I would like to ask 2 questions.

1) What are some problems I might miss by using -Wno-unused-value
? I thought it might disable the warning for unused variables,
but that is separate and covered by -Wunused-variables.

2) Is there a more targeted way to eliminate this spurious
warning? I'd hate to have to put pragmas every place I invoked
the macro.

Did you read the gcc man page? The one I looked at explains
what to do in the code to inhibit the warning for a specific
instance.
 
E

Edward A. Falk

Jorgen Grahn said:
I'm also asking because I know from experience that in the embedded
space you often find yourself locked to outdated tools.

Testify, brother! Working in C++ right now, with no STL. :(
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,755
Messages
2,569,534
Members
45,007
Latest member
obedient dusk

Latest Threads

Top