Velocity Reviews

Velocity Reviews (http://www.velocityreviews.com/forums/index.php)
-   C Programming (http://www.velocityreviews.com/forums/f42-c-programming.html)
-   -   Re: Multi-instructions macro and compiler warning (http://www.velocityreviews.com/forums/t754947-re-multi-instructions-macro-and-compiler-warning.html)

Ian Collins 10-16-2011 07:31 AM

Re: Multi-instructions macro and compiler warning
 
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

Ian Collins 10-16-2011 07:49 AM

Re: Multi-instructions macro and compiler warning
 
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

Ian Collins 10-16-2011 10:09 AM

Re: Multi-instructions macro and compiler warning
 
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

BartC 10-16-2011 11:47 AM

Re: Multi-instructions macro and compiler warning
 
"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



bert 10-16-2011 12:33 PM

Re: Multi-instructions macro and compiler warning
 
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);
--



Jorgen Grahn 10-16-2011 10:16 PM

Re: Multi-instructions macro and compiler warning
 
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 .

pozz 10-17-2011 09:37 AM

Re: Multi-instructions macro and compiler warning
 
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 :-(


pozz 10-17-2011 09:42 AM

Re: Multi-instructions macro and compiler warning
 
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...

Ian Collins 10-17-2011 10:04 AM

Re: Multi-instructions macro and compiler warning
 
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

Ben Bacarisse 10-17-2011 10:06 AM

Re: Multi-instructions macro and compiler warning
 
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.


All times are GMT. The time now is 12:04 PM.

Powered by vBulletin®. Copyright ©2000 - 2014, vBulletin Solutions, Inc.
SEO by vBSEO ©2010, Crawlability, Inc.