Multi-instructions macro and compiler warning

  • Follow


I'm trying to increase the warning level during compilation.  My goal is 
to reach the maximum warning level without any warning message after 
compilation.  I think this is a Good Thing to do when programming.

After changing warning level from 4 to 5, I received many warning 
messages of the type

   W1207C: conditional expression is constant: dowhile

Those messages refer to multi-instructions macros defined as below:

   #define MACRO(a, b)  do { foo(a); bar(b); } while(0)

Many times I read to use the trick do/while(0) to write 
multi-instruction macros to avoid other problems during compilation.  In 
this way, I can use MACRO() at any point where I could use a normal 
function.

How can I avoid the warning message W1207C?  I'm using an embedded 
microcontroller C compiler from Fujitsu, named Softune.
0
Reply pozzugno (150) 10/16/2011 7:09:54 AM

On 10/16/11 08:09 PM, pozz wrote:
> I'm trying to increase the warning level during compilation.  My goal is
> to reach the maximum warning level without any warning message after
> compilation.  I think this is a Good Thing to do when programming.
>
> After changing warning level from 4 to 5, I received many warning
> messages of the type
>
>     W1207C: conditional expression is constant: dowhile
>
> Those messages refer to multi-instructions macros defined as below:
>
>     #define MACRO(a, b)  do { foo(a); bar(b); } while(0)
>
> Many times I read to use the trick do/while(0) to write
> multi-instruction macros to avoid other problems during compilation.  In
> this way, I can use MACRO() at any point where I could use a normal
> function.
>
> How can I avoid the warning message W1207C?  I'm using an embedded
> microcontroller C compiler from Fujitsu, named Softune.

Use a function.  Any decent compiler will inline something that trivial.

-- 
Ian Collins
0
Reply ian-news (9881) 10/16/2011 7:31:33 AM


Il 16/10/2011 09:31, Ian Collins ha scritto:
> On 10/16/11 08:09 PM, pozz wrote:
>> I'm trying to increase the warning level during compilation. My goal is
>> to reach the maximum warning level without any warning message after
>> compilation. I think this is a Good Thing to do when programming.
>>
>> After changing warning level from 4 to 5, I received many warning
>> messages of the type
>>
>> W1207C: conditional expression is constant: dowhile
>>
>> Those messages refer to multi-instructions macros defined as below:
>>
>> #define MACRO(a, b) do { foo(a); bar(b); } while(0)
>>
>> Many times I read to use the trick do/while(0) to write
>> multi-instruction macros to avoid other problems during compilation. In
>> this way, I can use MACRO() at any point where I could use a normal
>> function.
>>
>> How can I avoid the warning message W1207C? I'm using an embedded
>> microcontroller C compiler from Fujitsu, named Softune.
>
> Use a function. Any decent compiler will inline something that trivial.

I have *many* macros of the same type (do/while(0)) in my projects, 
sparsed over source and include files.  The trivial MACRO() macro in my 
original post is just an example to describe my approach for 
multi-instructions macros.

Should I change a macro for a function just to avoid a warning from 
compiler?  It doesn't make sense to me.

And another curiosity.  Is a C compiler optimizer able to convert a 
function call to inline even if the function implementation (its code) 
is in a different C module file?
0
Reply pozzugno (150) 10/16/2011 7:41:10 AM

On 10/16/11 08:41 PM, pozz wrote:
> Il 16/10/2011 09:31, Ian Collins ha scritto:
>> On 10/16/11 08:09 PM, pozz wrote:
>>> I'm trying to increase the warning level during compilation. My goal is
>>> to reach the maximum warning level without any warning message after
>>> compilation. I think this is a Good Thing to do when programming.
>>>
>>> After changing warning level from 4 to 5, I received many warning
>>> messages of the type
>>>
>>> W1207C: conditional expression is constant: dowhile
>>>
>>> Those messages refer to multi-instructions macros defined as below:
>>>
>>> #define MACRO(a, b) do { foo(a); bar(b); } while(0)
>>>
>>> Many times I read to use the trick do/while(0) to write
>>> multi-instruction macros to avoid other problems during compilation. In
>>> this way, I can use MACRO() at any point where I could use a normal
>>> function.
>>>
>>> How can I avoid the warning message W1207C? I'm using an embedded
>>> microcontroller C compiler from Fujitsu, named Softune.
>>
>> Use a function. Any decent compiler will inline something that trivial.
>
> I have *many* macros of the same type (do/while(0)) in my projects,
> sparsed over source and include files.  The trivial MACRO() macro in my
> original post is just an example to describe my approach for
> multi-instructions macros.
>
> Should I change a macro for a function just to avoid a warning from
> compiler?  It doesn't make sense to me.

But changing them because function like macros are an anachronism (or an 
abomination, depending on your point of view) does make sense.

> And another curiosity.  Is a C compiler optimizer able to convert a
> function call to inline even if the function implementation (its code)
> is in a different C module file?

The compiler can't, but some linkers can.

-- 
Ian Collins
0
Reply ian-news (9881) 10/16/2011 7:49:33 AM

Il 16/10/2011 09:49, Ian Collins ha scritto:
> On 10/16/11 08:41 PM, pozz wrote:
>> And another curiosity. Is a C compiler optimizer able to convert a
>> function call to inline even if the function implementation (its code)
>> is in a different C module file?
>
> The compiler can't, but some linkers can.

I tried, the linker I'm using can't.  Also the compiler (even with 
optimization) doesn't transform normal functions to inline functions, 
without the inline keyword.


0
Reply pozzugno (150) 10/16/2011 8:16:52 AM

On 10/16/11 09:16 PM, pozz wrote:
> Il 16/10/2011 09:49, Ian Collins ha scritto:
>> On 10/16/11 08:41 PM, pozz wrote:
>>> And another curiosity. Is a C compiler optimizer able to convert a
>>> function call to inline even if the function implementation (its code)
>>> is in a different C module file?
>>
>> The compiler can't, but some linkers can.
>
> I tried, the linker I'm using can't.  Also the compiler (even with
> optimization) doesn't transform normal functions to inline functions,
> without the inline keyword.


So use it!  At least the compiler honours the hint.  Embedded compilers 
tend to offer more control over what is and isn't inlined than their 
hosted brethren.

-- 
Ian Collins
0
Reply ian-news (9881) 10/16/2011 10:09:27 AM

"pozz" <pozzugno@gmail.com> wrote in message
news:j7e1qm$7te$1@nnrp.ngi.it...
> Il 16/10/2011 09:31, Ian Collins ha scritto:

>> Use a function. Any decent compiler will inline something that trivial.

> And another curiosity.  Is a C compiler optimizer able to convert a
> function call to inline even if the function implementation (its code) is
> in a different C module file?

The body of a macro has to be visible to the program. The same can be done
with functions.

But sharing the same function across several modules means putting the
function definition in an include file, which is usually not done.

The code will be duplicated in each module, but that will happen many times
anyway if you want the function to be inlined.

You also need to put 'static' in front of the function definition to keep 
the name of each one local, otherwise they will all clash with each other.

-- 
Bartc
 

0
Reply bc (2211) 10/16/2011 11:47:19 AM

On Sunday, October 16, 2011 8:41:10 AM UTC+1, pozz wrote:
> Il 16/10/2011 09:31, Ian Collins ha scritto:
> > On 10/16/11 08:09 PM, pozz wrote:
> >> I'm trying to increase the warning level during compilation. My goal is
> >> to reach the maximum warning level without any warning message after
> >> compilation. I think this is a Good Thing to do when programming.
> >>
> >> After changing warning level from 4 to 5, I received many warning
> >> messages of the type
> >>
> >> W1207C: conditional expression is constant: dowhile
> >>
> >> Those messages refer to multi-instructions macros defined as below:
> >>
> >> #define MACRO(a, b) do { foo(a); bar(b); } while(0)
> >>
> >> Many times I read to use the trick do/while(0) to write
> >> multi-instruction macros to avoid other problems during compilation. In
> >> this way, I can use MACRO() at any point where I could use a normal
> >> function.
> >>
> >> How can I avoid the warning message W1207C? I'm using an embedded
> >> microcontroller C compiler from Fujitsu, named Softune.
> >
> > Use a function. Any decent compiler will inline something that trivial.
> 
> I have *many* macros of the same type (do/while(0)) in my projects, 
> sparsed over source and include files.  The trivial MACRO() macro in my 
> original post is just an example to describe my approach for 
> multi-instructions macros.
> 
> Should I change a macro for a function just to avoid a warning from 
> compiler?  It doesn't make sense to me.

I think he meant an in-lineable function 
something like:

int never(void)
{   return 0;
}

then use while(never()); instead of while(0);
-- 


0
Reply bert.hutchings (56) 10/16/2011 12:33:14 PM

On 10/16/2011 3:09 AM, pozz wrote:
> I'm trying to increase the warning level during compilation. My goal is
> to reach the maximum warning level without any warning message after
> compilation. I think this is a Good Thing to do when programming.

     It's a worthwhile goal to strive for, but not one you should
expect to achieve every time.

> After changing warning level from 4 to 5, I received many warning
> messages of the type
>
> W1207C: conditional expression is constant: dowhile
>
> Those messages refer to multi-instructions macros defined as below:
>
> #define MACRO(a, b) do { foo(a); bar(b); } while(0)

     For this particular case, you could try

	#define MACRO(a,b) ( (void)foo(a) , (void)bar(b) )

.... but this won't work if the expansion involves `for' or `return'
or other things that aren't expressions.

> Many times I read to use the trick do/while(0) to write
> multi-instruction macros to avoid other problems during compilation. In
> this way, I can use MACRO() at any point where I could use a normal
> function.

     No, you can't.  Try `return MACRO(x,y)', for example.

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

     An implementation must emit diagnostics when mandated by the
Standard, but is allowed to emit whatever additional diagnostics
it likes.  For example, some compilers issue diagnostic messages
for `if (x = y)', a perfectly valid C construct but possibly a
typo for `if (x == y)'.  Compiler writers invent these things in
an attempt to draw your attention to "suspicious" constructs, and
different compiler writers have different notions of "suspicious."

     ... which is why you cannot expect to get to "Zero warnings"
with every piece of code.  Some compiler, somewhere, will find
something "suspicious" to warn about.  You may be able to come
up with a work-around that will silence the particular compiler in
question (consult the compiler's documentation, or ask in a group
where this particular embedded toolchain is familiar).  Then again,
it may happen that no such work-around exists.  And it's highly
unlikely that you'll find a work-around that will pass muster with
every compiler everywhere.

.... but this approach will fail if the expansion involves `for'
or `return' or other non-expressions.

     So, seek to minimize warnings -- but don't expect to eliminate
them entirely.

-- 
Eric Sosman
esosman@ieee-dot-org.invalid
0
Reply esosman2 (2945) 10/16/2011 1:02:23 PM

On Oct 16, 8:09=A0am, pozz <pozzu...@gmail.com> wrote:

> How can I avoid the warning message W1207C? =A0I'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 =3D { 0 };" which is a common idiom for initialising
all members to zero. Another is a warning for "if (x >=3D 0 && x <=3D
100)" if the type of x happens to be unsigned. )
0
Reply christian.bau1 (402) 10/16/2011 2:40:36 PM

On 16 oct, 09:09, pozz

> I received many warning messages of the type
> =A0 =A0W1207C: conditional expression is constant: dowhile
> Those messages refer to multi-instructions macros defined as below:
> =A0 =A0#define MACRO(a, b) =A0do { foo(a); bar(b); } while(0)

Why not

#define MACRO(a,b)  { foo(a); bar(b); }
0
Reply 5.d (68) 10/16/2011 5:02:30 PM

On Sun, 16 Oct 2011 10:02:30 -0700, Jean-Christophe wrote:

> On 16 oct, 09:09, pozz
> 
>> I received many warning messages of the type
>>    W1207C: conditional expression is constant: dowhile
>> Those messages refer to multi-instructions macros defined as below:
>>    #define MACRO(a, b)  do { foo(a); bar(b); } while(0)
> 
> Why not
> 
> #define MACRO(a,b)  { foo(a); bar(b); }

The do...while construction requires a semicolon (i.e. will generate an error,
message if it's lacking), your construction doesn't. That's the usual reason to
do it that way.

-------------------------------------------------------------------------------
 ___________________________
< My vaseline is RUNNING... >
 ---------------------------
  \
   \
       ___  
     {~._.~}
      ( Y )
     ()~*~()   
     (_)-(_)   
-------------------------------------------------------------------------------

0
Reply kleuske8067 (92) 10/16/2011 5:44:05 PM

Jean-Christophe <5.d@free.fr> writes:
> On 16 oct, 09:09, pozz
>> I received many warning messages of the type
>>    W1207C: conditional expression is constant: dowhile
>> Those messages refer to multi-instructions macros defined as below:
>>    #define MACRO(a, b)  do { foo(a); bar(b); } while(0)
>
> Why not
>
> #define MACRO(a,b)  { foo(a); bar(b); }

See question 10.4 of the comp.lang.c FAQ, <http://c-faq.com/>.

The problem is that if you write:

    if(cond)
        MACRO(arg1, arg2);
    else
    /* some other code */

you get a syntax error due to the extra semicolon.  The
    do /* ... */ while (0)
idiom avoids that problem.

-- 
Keith Thompson (The_Other_Keith) kst-u@mib.org  <http://www.ghoti.net/~kst>
"We must do something.  This is something.  Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"
0
Reply kst-u (21474) 10/16/2011 8:49:02 PM

On 10/17/11 09:49 AM, Keith Thompson wrote:
> Jean-Christophe<5.d@free.fr>  writes:
>> On 16 oct, 09:09, pozz
>>> I received many warning messages of the type
>>>     W1207C: conditional expression is constant: dowhile
>>> Those messages refer to multi-instructions macros defined as below:
>>>     #define MACRO(a, b)  do { foo(a); bar(b); } while(0)
>>
>> Why not
>>
>> #define MACRO(a,b)  { foo(a); bar(b); }
>
> See question 10.4 of the comp.lang.c FAQ,<http://c-faq.com/>.
>
> The problem is that if you write:
>
>      if(cond)
>          MACRO(arg1, arg2);
>      else
>      /* some other code */
>
> you get a syntax error due to the extra semicolon.  The
>      do /* ... */ while (0)
> idiom avoids that problem.

So do functions!

-- 
Ian Collins
0
Reply ian-news (9881) 10/16/2011 9:00:55 PM

On Sun, 2011-10-16, BartC wrote:
....
> The body of a macro has to be visible to the program. The same can be done
> with functions.
>
> But sharing the same function across several modules means putting the
> function definition in an include file, which is usually not done.

Maybe it's usually not done, but it *should* be (if you have a modern
compiler).  Things which don't *have* to be macros should be inline
functions, for readability and type safety.

/Jorgen

-- 
  // Jorgen Grahn <grahn@  Oo  o.   .     .
\X/     snipabacken.se>   O  o   .
0
Reply nntp24 (1556) 10/16/2011 10:16:02 PM

On 16 Ott, 12:09, Ian Collins <ian-n...@hotmail.com> wrote:
> On 10/16/11 09:16 PM, pozz wrote:
> > I tried, the linker I'm using can't. =A0Also the compiler (even with
> > optimization) doesn't transform normal functions to inline functions,
> > without the inline keyword.
>
> So use it! =A0At least the compiler honours the hint. =A0Embedded compile=
rs
> tend to offer more control over what is and isn't inlined than their
> hosted brethren.

Unfortunately, I have another "warning" problem if I use inline
functions.

Suppose I have a macro that activate a relay connected to a
microcontroller pin:

  #define RELAY_ON()  do {PIN_SET_OUTPUT(10); PIN_SET(PIN(10));}
while(0)

The first instruction is to configure the pin as an output; the second
is to set its level to high.

Transforming this macro to an inline function, I would write:

  #pragma inline relay_on
  void relay_on(void) {
    PIN_SET_OUTPUT(10);
    PIN_SET(PIN(10));
  }

If this function is accessible just from one compilation module, it is
simple to use it:

-- test.c --
#include "cpu.h"

#pragma inline relay_on
static void relay_on(void) {
  PIN_SET_OUTPUT(10);
  PIN_SET(PIN(10));
}

void test(void) {
  relay_on();
  /* other things */
}
-- test.h --
#ifndef TEST_H
#define TEST_H
#include "test.h"
void test(void);
#endif
--

The compilation ends without any errors and warnings.

The problem happens when I try to use this function in more than one
module,
so moving the code to include file (I think this is the way to have an
extern
inline function):

-- test.h --
#ifndef TEST_H
#define TEST_H

#pragma inline relay_on
void relay_on(void) {
  PIN_SET_OUTPUT(10);
  PIN_SET(PIN(10));
}

#endif
--

If I include test.h in more than one file, the compilation ends with
the warning

  W1327L: Duplicate symbol definition (_relay_on)

even if the function relay_on() is never used. So the use of inline
function to
avoid a warning has produced another warning :-(

0
Reply pozzugno (150) 10/17/2011 9:37:31 AM

On 16 Ott, 13:47, "BartC" <b...@freeuk.com> wrote:
> The body of a macro has to be visible to the program. The same can be done
> with functions.
>
> But sharing the same function across several modules means putting the
> function definition in an include file, which is usually not done.

So isn't it possible to share an inline function among several
modules?


> The code will be duplicated in each module, but that will happen many times
> anyway if you want the function to be inlined.
>
> You also need to put 'static' in front of the function definition to keep
> the name of each one local, otherwise they will all clash with each other.

I tried with:

-- test.h --
#ifndef TEST_H
#define TEST_H

#pragma inline relay_on
static void relay_on(void) {
  PIN_SET_OUTPUT(10);
  PIN_SET(PIN(10));
}

#endif
--

but now I receive a warning message from the compiler if one module
includes
test.h without using relay_on() function (and this could be possible,
because
I usually have other definitions in the include file):

  W1204C: static symbol `relay_on' unused

It's a nightmare...
0
Reply pozzugno (150) 10/17/2011 9:42:23 AM

On 10/17/11 10:37 PM, pozz wrote:
> On 16 Ott, 12:09, Ian Collins<ian-n...@hotmail.com>  wrote:
>> On 10/16/11 09:16 PM, pozz wrote:
>>> I tried, the linker I'm using can't.  Also the compiler (even with
>>> optimization) doesn't transform normal functions to inline functions,
>>> without the inline keyword.
>>
>> So use it!  At least the compiler honours the hint.  Embedded compilers
>> tend to offer more control over what is and isn't inlined than their
>> hosted brethren.
>
> Unfortunately, I have another "warning" problem if I use inline
> functions.
>
> Suppose I have a macro that activate a relay connected to a
> microcontroller pin:
>
>    #define RELAY_ON()  do {PIN_SET_OUTPUT(10); PIN_SET(PIN(10));}
> while(0)
>
> The first instruction is to configure the pin as an output; the second
> is to set its level to high.
>
> Transforming this macro to an inline function, I would write:
>
>    #pragma inline relay_on
>    void relay_on(void) {
>      PIN_SET_OUTPUT(10);
>      PIN_SET(PIN(10));
>    }
>
> If this function is accessible just from one compilation module, it is
> simple to use it:
>
> -- test.c --
> #include "cpu.h"
>
> #pragma inline relay_on
> static void relay_on(void) {
>    PIN_SET_OUTPUT(10);
>    PIN_SET(PIN(10));
> }
>
> void test(void) {
>    relay_on();
>    /* other things */
> }
> -- test.h --
> #ifndef TEST_H
> #define TEST_H
> #include "test.h"
> void test(void);
> #endif
> --
>
> The compilation ends without any errors and warnings.
>
> The problem happens when I try to use this function in more than one
> module,
> so moving the code to include file (I think this is the way to have an
> extern
> inline function):
>
> -- test.h --
> #ifndef TEST_H
> #define TEST_H
>
> #pragma inline relay_on
> void relay_on(void) {
>    PIN_SET_OUTPUT(10);
>    PIN_SET(PIN(10));
> }
>
> #endif
> --
>
> If I include test.h in more than one file, the compilation ends with
> the warning
>
>    W1327L: Duplicate symbol definition (_relay_on)
>
> even if the function relay_on() is never used. So the use of inline
> function to
> avoid a warning has produced another warning :-(
>
Well your "#pragma inline" doesn't follow the rules for inline 
functions.  if the compiler did,

inline void relay_on(void) {}

would avoid multiple inclusion.

Try "static void " rather than "inline void", it should have the same 
effect.

-- 
Ian Collins
0
Reply ian-news (9881) 10/17/2011 10:04:05 AM

pozz <pozzugno@gmail.com> writes:
<snip>
> Unfortunately, I have another "warning" problem if I use inline
> functions.
<snip>
> Transforming this macro to an inline function, I would write:
>
>   #pragma inline relay_on
>   void relay_on(void) {
>     PIN_SET_OUTPUT(10);
>     PIN_SET(PIN(10));
>   }
>
> If this function is accessible just from one compilation module, it is
> simple to use it:
<snip>
> The problem happens when I try to use this function in more than one
> module,
> so moving the code to include file (I think this is the way to have an
> extern
> inline function):
>
> -- test.h --
> #ifndef TEST_H
> #define TEST_H
>
> #pragma inline relay_on
> void relay_on(void) {
>   PIN_SET_OUTPUT(10);
>   PIN_SET(PIN(10));
> }
>
> #endif
> --
>
> If I include test.h in more than one file, the compilation ends with
> the warning
>
>   W1327L: Duplicate symbol definition (_relay_on)
>
> even if the function relay_on() is never used. So the use of inline
> function to
> avoid a warning has produced another warning :-(

Make the function static.

-- 
Ben.
0
Reply ben.usenet (6515) 10/17/2011 10:06:10 AM

On 17 Ott, 12:06, Ben Bacarisse <ben.use...@bsb.me.uk> wrote:
> pozz <pozzu...@gmail.com> writes:
>
> <snip>
>
>
>
>
>
>
>
>
>
> > Unfortunately, I have another "warning" problem if I use inline
> > functions.
> <snip>
> > Transforming this macro to an inline function, I would write:
>
> > =A0 #pragma inline relay_on
> > =A0 void relay_on(void) {
> > =A0 =A0 PIN_SET_OUTPUT(10);
> > =A0 =A0 PIN_SET(PIN(10));
> > =A0 }
>
> > If this function is accessible just from one compilation module, it is
> > simple to use it:
> <snip>
> > The problem happens when I try to use this function in more than one
> > module,
> > so moving the code to include file (I think this is the way to have an
> > extern
> > inline function):
>
> > -- test.h --
> > #ifndef TEST_H
> > #define TEST_H
>
> > #pragma inline relay_on
> > void relay_on(void) {
> > =A0 PIN_SET_OUTPUT(10);
> > =A0 PIN_SET(PIN(10));
> > }
>
> > #endif
> > --
>
> > If I include test.h in more than one file, the compilation ends with
> > the warning
>
> > =A0 W1327L: Duplicate symbol definition (_relay_on)
>
> > even if the function relay_on() is never used. So the use of inline
> > function to
> > avoid a warning has produced another warning :-(
>
> Make the function static.

See my answer to BartC below. If I declare the inline function static,
I receive
a warning when I include the file without using the function... :-(
0
Reply pozzugno (150) 10/17/2011 10:23:53 AM

"pozz" <pozzugno@gmail.com> wrote in message 
news:8a974a79-9ee2-4f6f-8aa6-795b80b03080@x20g2000vbl.googlegroups.com...
> On 16 Ott, 13:47, "BartC" <b...@freeuk.com> wrote:

>> The code will be duplicated in each module, but that will happen many 
>> times
>> anyway if you want the function to be inlined.

> -- test.h --
> #ifndef TEST_H
> #define TEST_H
>
> #pragma inline relay_on
> static void relay_on(void) {
>  PIN_SET_OUTPUT(10);
>  PIN_SET(PIN(10));
> }
>
> #endif
> --
>
> but now I receive a warning message from the compiler if one module
> includes
> test.h without using relay_on() function (and this could be possible,
> because
> I usually have other definitions in the include file):
>
>  W1204C: static symbol `relay_on' unused
>
> It's a nightmare...

No, it's just a warning, not an error.

You can ignore the warning. Or find some compiler switch that turns the 
warning off.

Or create a more complex include file scheme, so that these functions are 
declared in their own header, and included only when used. Or use a dummy 
function that makes use of 'relay_on' (that's assuming that doesn't generate 
yet another warning about not calling the dummy function...)

-- 
Bartc 

0
Reply bc (2211) 10/17/2011 12:10:07 PM

On Oct 16, 10:40=A0am, "christian.bau"
<christian....@cbau.wanadoo.co.uk> wrote:
> On Oct 16, 8:09=A0am, pozz <pozzu...@gmail.com> wrote:
>
> > How can I avoid the warning message W1207C? =A0I'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 =3D { 0 };" which is a common idiom for initialising
> all members to zero. Another is a warning for "if (x >=3D 0 && x <=3D
> 100)" if the type of x happens to be unsigned. )

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

Best regards,
John D.
0
Reply jadill33 (201) 10/17/2011 3:07:21 PM

On Oct 17, 4:07=A0pm, ImpalerCore <jadil...@gmail.com> wrote:
> On Oct 16, 10:40=A0am, "christian.bau"
>
>
>
>
>
>
>
>
>
> <christian....@cbau.wanadoo.co.uk> wrote:
> > On Oct 16, 8:09=A0am, pozz <pozzu...@gmail.com> wrote:
>
> > > How can I avoid the warning message W1207C? =A0I'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 =3D { 0 };" which is a common idiom for initialising
> > all members to zero. Another is a warning for "if (x >=3D 0 && x <=3D
> > 100)" if the type of x happens to be unsigned. )
>
> If 'x' is unsigned, I would think that one could use 'if (/*x >=3D 0
> &&*/ x <=3D 100)' to document the condition while removing the warning,
> as the 'x >=3D 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 =3D 0 } or enum { lowerlimit =3D 1 }

and I should be allowed to write if (x >=3D lowerlimit && x <=3D
upperlimit) ... no matter what the particular value of lowerlimit is.
A method that works but is just daft is writing if ((x > lowerlimit ||
x =3D=3D lowerlimit) && x <=3D 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.
0
Reply christian.bau1 (402) 10/17/2011 4:25:21 PM

On 10/16/2011 3:09 AM, pozz wrote:
[...]
> After changing warning level from 4 to 5, I received many warning messages
> of the type
>
> W1207C: conditional expression is constant: dowhile
[...]
> How can I avoid the warning message W1207C? I'm using an embedded
> microcontroller C compiler from Fujitsu, named Softune.

The compiler may have a command-line flag or a #pragma which turns off such 
warnings.  The only "portable" way to do such a thing is to use some other 
construct, such as an inline function.

-- 
Kenneth Brody
0
Reply kenbrody (1860) 10/17/2011 4:50:27 PM

On 10/17/2011 12:25 PM, christian.bau wrote:
> On Oct 17, 4:07 pm, ImpalerCore <jadil...@gmail.com> 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.

0
Reply jameskuyper (5159) 10/17/2011 4:58:21 PM

On Oct 17, 12:25=A0pm, "christian.bau"
<christian....@cbau.wanadoo.co.uk> wrote:
> On Oct 17, 4:07=A0pm, ImpalerCore <jadil...@gmail.com> wrote:
>
>
>
> > On Oct 16, 10:40=A0am, "christian.bau"
>
> > <christian....@cbau.wanadoo.co.uk> wrote:
> > > On Oct 16, 8:09=A0am, pozz <pozzu...@gmail.com> wrote:
>
> > > > How can I avoid the warning message W1207C? =A0I'm using an embedde=
d
> > > > 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 a=
s
> > > "struct soandso x =3D { 0 };" which is a common idiom for initialisin=
g
> > > all members to zero. Another is a warning for "if (x >=3D 0 && x <=3D
> > > 100)" if the type of x happens to be unsigned. )
>
> > If 'x' is unsigned, I would think that one could use 'if (/*x >=3D 0
> > &&*/ x <=3D 100)' to document the condition while removing the warning,
> > as the 'x >=3D 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 =3D 0 } or enum { lowerlimit =3D 1 }
>
> and I should be allowed to write if (x >=3D lowerlimit && x <=3D
> upperlimit) ... no matter what the particular value of lowerlimit is.
> A method that works but is just daft is writing if ((x > lowerlimit ||
> x =3D=3D lowerlimit) && x <=3D 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 >=3D 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.
0
Reply jadill33 (201) 10/17/2011 5:41:49 PM

On Mon, 17 Oct 2011 12:50:27 -0400, Kenneth Brody <kenbrody@spamcop.net>  
wrote:

> On 10/16/2011 3:09 AM, pozz wrote:
> [...]
>> After changing warning level from 4 to 5, I received many warning  
>> messages
>> of the type
>>
>> W1207C: conditional expression is constant: dowhile
> [...]
>> How can I avoid the warning message W1207C? I'm using an embedded
>> microcontroller C compiler from Fujitsu, named Softune.
>
> The compiler may have a command-line flag or a #pragma which turns off  
> such warnings.  The only "portable" way to do such a thing is to use  
> some other construct, such as an inline function.

or perhaps

     [compile-command] | grep -v W1207C

-- 
Morris Keesan -- mkeesan@post.harvard.edu
0
Reply mkeesan (160) 10/17/2011 6:50:26 PM

pozz <pozzugno@gmail.com> writes:
[...]
> Suppose I have a macro that activate a relay connected to a
> microcontroller pin:
>
>   #define RELAY_ON()  do {PIN_SET_OUTPUT(10); PIN_SET(PIN(10));}
> while(0)
[...]

Are PIN_SET_OUTPUT and PIN_SET functions or macros?

If they're functions, or if they're macros whose invocations expand to
valid expressions, then you can just do this:

    #define RELAY_ON() ( PIN_SET_OUTPUT(10), PIN_SET(PIN(10)) )

There's no need for the "do { ... } while (0)" trick unless you
need to use control-flow constructs (if, for, while) -- and "if"
can often be replaced with "?:".  Just about anything that doesn't
require looping can be made into an expression.

This assumes you really need to make it a macro.  If you're able
to make it a function (inline or not), then of course you can use
any control-flow you like.

-- 
Keith Thompson (The_Other_Keith) kst-u@mib.org  <http://www.ghoti.net/~kst>
"We must do something.  This is something.  Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"
0
Reply kst-u (21474) 10/17/2011 7:30:28 PM

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<jadil...@gmail.com>  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
esosman@ieee-dot-org.invalid
0
Reply esosman2 (2945) 10/18/2011 11:43:19 AM

Eric Sosman <esosman@ieee-dot-org.invalid> 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) kst-u@mib.org  <http://www.ghoti.net/~kst>
"We must do something.  This is something.  Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"
0
Reply kst-u (21474) 10/18/2011 6:52:46 PM

29 Replies
33 Views

(page loaded in 0.255 seconds)


Reply: