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

 
 
Ian Collins
Guest
Posts: n/a
 
      10-16-2011
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
 
Reply With Quote
 
 
 
 
Ian Collins
Guest
Posts: n/a
 
      10-16-2011
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
 
Reply With Quote
 
 
 
 
Ian Collins
Guest
Posts: n/a
 
      10-16-2011
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
 
Reply With Quote
 
BartC
Guest
Posts: n/a
 
      10-16-2011
"pozz" <(E-Mail Removed)> wrote in message
news:j7e1qm$7te$(E-Mail Removed)...
> 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


 
Reply With Quote
 
bert
Guest
Posts: n/a
 
      10-16-2011
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);
--


 
Reply With Quote
 
Jorgen Grahn
Guest
Posts: n/a
 
      10-16-2011
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 .
 
Reply With Quote
 
pozz
Guest
Posts: n/a
 
      10-17-2011
On 16 Ott, 12:09, Ian Collins <(E-Mail Removed)> 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

 
Reply With Quote
 
pozz
Guest
Posts: n/a
 
      10-17-2011
On 16 Ott, 13:47, "BartC" <(E-Mail Removed)> 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...
 
Reply With Quote
 
Ian Collins
Guest
Posts: n/a
 
      10-17-2011
On 10/17/11 10:37 PM, pozz wrote:
> On 16 Ott, 12:09, Ian Collins<(E-Mail Removed)> 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
 
Reply With Quote
 
Ben Bacarisse
Guest
Posts: n/a
 
      10-17-2011
pozz <(E-Mail Removed)> 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.
 
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 ImpalerCore C Programming 4 10-18-2011 06:52 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