Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C Programming > Re: Multi-instructions macro and compiler warning

Reply
Thread Tools

Re: Multi-instructions macro and compiler warning

 
 
ImpalerCore
Guest
Posts: n/a
 
      10-17-2011
On Oct 16, 10:40*am, "christian.bau"
<(E-Mail Removed)> wrote:
> On Oct 16, 8:09*am, pozz <(E-Mail Removed)> wrote:
>
> > How can I avoid the warning message W1207C? *I'm using an embedded
> > microcontroller C compiler from Fujitsu, named Softune.

>
> Many compilers give good warnings, but also rubbish warnings. You
> certainly want your code to be free of warnings with the compiler
> settings that you use, so that you notice whenever a new warning pops
> up. But as you noticed yourself, being free of warnings with all
> warnings in the compiler turned on is not a worthwhile goal.
>
> "do { ... } while (0)", especially as the body of a macro, is such a
> common idiom that getting a warning for it is wrong, and changing the
> code to avoid the warning is wrong as well. Change the compiler
> settings to avoid this warning, possibly complain to the compiler
> maker.
>
> (One of my negative favorites is warnings for initialising a struct as
> "struct soandso x = { 0 };" which is a common idiom for initialising
> all members to zero. Another is a warning for "if (x >= 0 && x <=
> 100)" if the type of x happens to be unsigned. )


If 'x' is unsigned, I would think that one could use 'if (/*x >= 0
&&*/ x <= 100)' to document the condition while removing the warning,
as the 'x >= 0' condition is implicit from the use of an unsigned
type.

Best regards,
John D.
 
Reply With Quote
 
 
 
 
James Kuyper
Guest
Posts: n/a
 
      10-17-2011
On 10/17/2011 12:25 PM, christian.bau wrote:
> On Oct 17, 4:07 pm, ImpalerCore <(E-Mail Removed)> wrote:
>> On Oct 16, 10:40 am, "christian.bau"

....
>>> all members to zero. Another is a warning for "if (x >= 0 && x <=
>>> 100)" if the type of x happens to be unsigned. )

>>
>> If 'x' is unsigned, I would think that one could use 'if (/*x >= 0
>> &&*/ x <= 100)' to document the condition while removing the warning,
>> as the 'x >= 0' condition is implicit from the use of an unsigned
>> type.

....
> The point is that the warning in this case is completely pointless.


No - it catches a very common mistake: forgetting that the expression
being tested is incapable, because of it's type, of failing the test.
This is very often a sign that the user wasn't thinking about the fact
that the expression was unsigned; and is often accompanied by code that
will not do what the author expected it to do, for that same reason.
That this was not true in this particular case doesn't invalidate
generation of the warning.

 
Reply With Quote
 
 
 
 
ImpalerCore
Guest
Posts: n/a
 
      10-17-2011
On Oct 17, 12:25*pm, "christian.bau"
<(E-Mail Removed)> wrote:
> On Oct 17, 4:07*pm, ImpalerCore <(E-Mail Removed)> wrote:
>
>
>
> > On Oct 16, 10:40*am, "christian.bau"

>
> > <(E-Mail Removed)> wrote:
> > > On Oct 16, 8:09*am, pozz <(E-Mail Removed)> wrote:

>
> > > > How can I avoid the warning message W1207C? *I'm using an embedded
> > > > microcontroller C compiler from Fujitsu, named Softune.

>
> > > Many compilers give good warnings, but also rubbish warnings. You
> > > certainly want your code to be free of warnings with the compiler
> > > settings that you use, so that you notice whenever a new warning pops
> > > up. But as you noticed yourself, being free of warnings with all
> > > warnings in the compiler turned on is not a worthwhile goal.

>
> > > "do { ... } while (0)", especially as the body of a macro, is such a
> > > common idiom that getting a warning for it is wrong, and changing the
> > > code to avoid the warning is wrong as well. Change the compiler
> > > settings to avoid this warning, possibly complain to the compiler
> > > maker.

>
> > > (One of my negative favorites is warnings for initialising a struct as
> > > "struct soandso x = { 0 };" which is a common idiom for initialising
> > > all members to zero. Another is a warning for "if (x >= 0 && x <=
> > > 100)" if the type of x happens to be unsigned. )

>
> > If 'x' is unsigned, I would think that one could use 'if (/*x >= 0
> > &&*/ x <= 100)' to document the condition while removing the warning,
> > as the 'x >= 0' condition is implicit from the use of an unsigned
> > type.

>
> Well, there are cases where a value x should be between some lower and
> upper limit, and I would want to check for this condition without
> having to write different code when the lower and upper limit have
> some specific value. So I might have defined somewhere
>
> enum { lowerlimit = 0 } or enum { lowerlimit = 1 }
>
> and I should be allowed to write if (x >= lowerlimit && x <=
> upperlimit) ... no matter what the particular value of lowerlimit is.
> A method that works but is just daft is writing if ((x > lowerlimit ||
> x == lowerlimit) && x <= upperlimit) ...
>
> The point is that the warning in this case is completely pointless.
> Same as the OP's warning for a do ... while (0) construct is
> completely pointless. And the OP is looking at ways to write far
> inferior code to remove warnings. In other words, warnings that should
> help improving the code make it actually worse.


Unfortunately, the warning indicates a common logic flaw. While
'always true' or 'always false' warnings are easily ignored by the
original writer of the statement, it often gives pause to the next
person that comes across it. The 'do ... while(0)' is a common idiom;
an 'if ( x >= 0 && ... )' statement when 'x' is unsigned is not (in my
experiences). While in these particular cases, the intent is pretty
clear and the warning appears superfluous; in the general case it can
indicate a serious logic flaw. Most compilers won't know the
difference.

Best regards,
John D.
 
Reply With Quote
 
Eric Sosman
Guest
Posts: n/a
 
      10-18-2011
On 10/17/2011 12:58 PM, James Kuyper wrote:
> On 10/17/2011 12:25 PM, christian.bau wrote:
>> On Oct 17, 4:07 pm, ImpalerCore<(E-Mail Removed)> wrote:
>>> On Oct 16, 10:40 am, "christian.bau"

> ...
>>>> all members to zero. Another is a warning for "if (x>= 0&& x<=
>>>> 100)" if the type of x happens to be unsigned. )
>>>
>>> If 'x' is unsigned, I would think that one could use 'if (/*x>= 0
>>> &&*/ x<= 100)' to document the condition while removing the warning,
>>> as the 'x>= 0' condition is implicit from the use of an unsigned
>>> type.

> ...
>> The point is that the warning in this case is completely pointless.

>
> No - it catches a very common mistake: forgetting that the expression
> being tested is incapable, because of it's type, of failing the test.
> This is very often a sign that the user wasn't thinking about the fact
> that the expression was unsigned; and is often accompanied by code that
> will not do what the author expected it to do, for that same reason.
> That this was not true in this particular case doesn't invalidate
> generation of the warning.


In a related case, a colleague once got a warning that

if (thing.field > 0) foo(); else bar();

.... was a vacuous test which would always result in calling bar(),
never foo(). Investigating, he found

struct { int field : 1; /*...*/ } thing;

The catch is that a plain `int' bit-field may be signed or unsigned
at the compiler's discretion. On the compiler where the code was first
developed such bit-fields were unsigned, so `field' could store either
zero or one and the `if' made sense. The compiler that issued the
warning treated bit-fields as signed, so `field' had one sign bit and
no value bits; its only possible (two's complement) values were zero
and minus one. Adding an `unsigned' fixed things.

Thus, the warning about restricted range led to the detection of
an actual portability bug that had been sitting in the code since
whoknowswhen. That's far from "completely pointless."

--
Eric Sosman
http://www.velocityreviews.com/forums/(E-Mail Removed)d
 
Reply With Quote
 
Keith Thompson
Guest
Posts: n/a
 
      10-18-2011
Eric Sosman <(E-Mail Removed)> writes:
[...]
> In a related case, a colleague once got a warning that
>
> if (thing.field > 0) foo(); else bar();
>
> ... was a vacuous test which would always result in calling bar(),
> never foo(). Investigating, he found
>
> struct { int field : 1; /*...*/ } thing;
>
> The catch is that a plain `int' bit-field may be signed or unsigned
> at the compiler's discretion. On the compiler where the code was first
> developed such bit-fields were unsigned, so `field' could store either
> zero or one and the `if' made sense. The compiler that issued the
> warning treated bit-fields as signed, so `field' had one sign bit and
> no value bits; its only possible (two's complement) values were zero
> and minus one. Adding an `unsigned' fixed things.
>
> Thus, the warning about restricted range led to the detection of
> an actual portability bug that had been sitting in the code since
> whoknowswhen. That's far from "completely pointless."


The problem is that compilers aren't smart enough to tell the difference
between sensible warnings and silly warnings.

Which is probably why most of us are still employed.

--
Keith Thompson (The_Other_Keith) (E-Mail Removed) <http://www.ghoti.net/~kst>
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Re: Multi-instructions macro and compiler warning Ian Collins C Programming 12 10-17-2011 07:30 PM
Re: Multi-instructions macro and compiler warning Jean-Christophe C Programming 3 10-16-2011 09:00 PM
Suppressing Compiler Warning About Tricky Macro Michael B Allen C Programming 6 07-22-2007 10:52 PM
warning C4267 and warning C4996 B. Williams C++ 17 10-27-2006 09:41 PM
#define macro to enclose an older macro with strings Dead RAM C++ 20 07-14-2004 10:58 AM



Advertisments