473,322 Members | 1,473 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,322 software developers and data experts.

Macro that allocates storage and "returns" value


I am replacing a number of functions with macros. Some of these
functions "do something" and then return a variable. This behaviour I
have found that I can emulate using the comma operator:

#define MYMACRO (do_something(), file_scope_variable - get_a_value() )
Other functions need local storage (but do not return a value), and
can be emulated using a block (a compund statement) to provide a scope
for a variable:

#define OTHERMACRO(some_var) \
{ \
uint8_t k; \
get_some_value(&k); \
some_var += k; \
}
The problem I have run into is a to replace a function that does both
of these, i.e. it both needs to allocate local storage and returns a
value. This seems to be problematic. I think (as far as I have found
in the standard) that a statement (e.g. a compund statement) does not
have (yield) a value. An introducing a block into a comma operator
expression gives compilation errors.

The C FAQ lists a number of techniques, but none of those seem to do
what I want here.) Is there a way to write a macro that can replace
such a function, or am I correct in assuming that it is not possible?
Asbjørn Sæbø
Jan 9 '08 #1
9 1984
Asbjørn Sæbø wrote:
I am replacing a number of functions with macros.
Why?
(Confession - I'm allergic to macros, by and large, and avoid them
whenever possible).
Some of these
functions "do something" and then return a variable. This behaviour I
have found that I can emulate using the comma operator:

#define MYMACRO (do_something(), file_scope_variable - get_a_value() )
OK.
Other functions need local storage (but do not return a value), and
can be emulated using a block (a compund statement) to provide a scope
for a variable:

#define OTHERMACRO(some_var) \
{ \
uint8_t k; \
get_some_value(&k); \
some_var += k; \
}
It's usually recommended to use do { } while(0) or some
similar hackery, so you can add ";" - see q10.4 in
http://www.c-faq.com
>

The problem I have run into is a to replace a function that does both
of these, i.e. it both needs to allocate local storage and returns a
value. This seems to be problematic. I think (as far as I have found
in the standard) that a statement (e.g. a compund statement) does not
have (yield) a value. An introducing a block into a comma operator
expression gives compilation errors.

The C FAQ lists a number of techniques, but none of those seem to do
what I want here.) Is there a way to write a macro that can replace
such a function, or am I correct in assuming that it is not possible?
It's not (portably) possible. GCC has a mechanism which can do this -
http://gcc.gnu.org/onlinedocs/gcc-4....tatement-Exprs
- but it's non-standard.

Otherwise, inline functions (where available) are probably the way
forward.
Jan 9 '08 #2
=?utf-8?b?QXNiasO4cm4gU8OmYsO4?= wrote:
>
I am replacing a number of functions with macros. Some of these
functions "do something" and then return a variable. This behaviour I
have found that I can emulate using the comma operator:

#define MYMACRO (do_something(), file_scope_variable - get_a_value() )

Other functions need local storage (but do not return a value), and
can be emulated using a block (a compund statement) to provide a scope
for a variable:

#define OTHERMACRO(some_var) \
{ \
uint8_t k; \
get_some_value(&k); \
some_var += k; \
}

The problem I have run into is a to replace a function that does both
of these, i.e. it both needs to allocate local storage and returns a
value. This seems to be problematic. I think (as far as I have found
in the standard) that a statement (e.g. a compund statement) does not
have (yield) a value. An introducing a block into a comma operator
expression gives compilation errors.

The C FAQ lists a number of techniques, but none of those seem to do
what I want here.) Is there a way to write a macro that can replace
such a function, or am I correct in assuming that it is not possible?
My philosophy is that when a macro starts reserving memory,
then it's doing the job that functions were intended for,
and it's probably better to use a function instead in that case.

--
pete
Jan 9 '08 #3
Asbjørn Sæbø <in*****@invalid.invalidwrites:
I am replacing a number of functions with macros. Some of these
functions "do something" and then return a variable. This behaviour I
have found that I can emulate using the comma operator:

#define MYMACRO (do_something(), file_scope_variable - get_a_value() )
Why are you replacing functions with macros? It sounds like
functions are more appropriate for this use case.
--
char a[]="\n .CJacehknorstu";int putchar(int);int main(void){unsigned long b[]
={0x67dffdff,0x9aa9aa6a,0xa77ffda9,0x7da6aa6a,0xa6 7f6aaa,0xaa9aa9f6,0x11f6},*p
=b,i=24;for(;p+=!*p;*p/=4)switch(0[p]&3)case 0:{return 0;for(p--;i--;i--)case+
2:{i++;if(i)break;else default:continue;if(0)case 1:putchar(a[i&15]);break;}}}
Jan 9 '08 #4
Asbjørn Sæbø <as***@stud.ntnu.nowrites:
Ben Pfaff <bl*@cs.stanford.eduwrites:
>Asbjørn Sæbø <in*****@invalid.invalidwrites:
I am replacing a number of functions with macros. Some of these
functions "do something" and then return a variable. This behaviour I
have found that I can emulate using the comma operator:

#define MYMACRO (do_something(), file_scope_variable - get_a_value() )

Why are you replacing functions with macros? It sounds like
functions are more appropriate for this use case.

Indeed they are, except for the fact that I am working on an embedded
platform and having "multiple call" problems, with functions being
called both from main() and from interrupts. Replacing functions with
macros is one step towards one way of solving this.
Why not compile two copies of them, then, giving each copy a
different name? You could use macro tricks to change the names,
so that you only had one copy of each function in the source
code.
--
"Some programming practices beg for errors;
this one is like calling an 800 number
and having errors delivered to your door."
--Steve McConnell
Jan 9 '08 #5
Asbjørn Sæbø wrote, On 09/01/08 21:37:
Ben Pfaff <bl*@cs.stanford.eduwrites:
>Asbjørn Sæbø <in*****@invalid.invalidwrites:
>>I am replacing a number of functions with macros. Some of these
functions "do something" and then return a variable. This behaviour I
have found that I can emulate using the comma operator:

#define MYMACRO (do_something(), file_scope_variable - get_a_value() )
Why are you replacing functions with macros? It sounds like
functions are more appropriate for this use case.

Indeed they are, except for the fact that I am working on an embedded
platform and having "multiple call" problems, with functions being
called both from main() and from interrupts. Replacing functions with
macros is one step towards one way of solving this.
It is a truly horrible way of solving it in my opinion. Better ways
would include:
Making the functions safely re-entrant
Making the functions inline if your compiler supports this
If the ISRs do not need to be re-entrant, but each in a separate
source file and provide static copies of the non-re-entrant functions
for the ISRs.

Note that using macros instead of functions will not solve re-entrancy
problems if your ISRs need to be re-entrant (I've done re-entrant ISRs,
but I would not recommend them to everyone).
--
Flash Gordon
Jan 9 '08 #6
In article <dn************@news.flash-gordon.me.uk>,
Flash Gordon <sp**@flash-gordon.me.ukwrote:
>Asbjørn Sæbø wrote, On 09/01/08 21:37:
>Ben Pfaff <bl*@cs.stanford.eduwrites:
>>Why are you replacing functions with macros? It sounds like
functions are more appropriate for this use case.
>Indeed they are, except for the fact that I am working on an embedded
platform and having "multiple call" problems, with functions being
called both from main() and from interrupts. Replacing functions with
macros is one step towards one way of solving this.
>It is a truly horrible way of solving it in my opinion. Better ways
would include:
Making the functions safely re-entrant
Making the functions inline if your compiler supports this
As the poster mentioned in another part of this thread that his
embedded system has no stack, my *speculation* was that it does not
have "return addresses" for functions, and the compiler is doing
a static branch to the function and static return -- which would
only allow each function to be called once. (Which doesn't explain
how the standard library would work, but since it is an embedded
system at least the poster would not have I/O portion of the
standard library to be concerned with.)

If this speculation were correct, it would be consistant with
"local variables" being possible if the compiler in question
ended up allocating the "local variables" at (possibly overlapping)
fixed addresses.

The result would not be consistant with the C standards in that
it would not allow recursion, but that might not be a problem
in that application environment.

This kind of construct of "no stack" could be extended to handle
multiple calls to the same routine if instead of using static
return addresses, the compiler used the equivilent of the old
IBM 360 BALR (Branch and Link Register), in which the return address
was put into a specific register instead of being put onto a
"stack". Multiple call levels could be handled by storing the
old return address in the fixed-addressed (possibly overlapped)
local variables possibility mentioned above. On the other hand,
I cannot think right at the moment why this would present problems
with "multiple calls" or ISRs.
--
"Okay, buzzwords only. Two syllables, tops." -- Laurie Anderson
Jan 10 '08 #7
Walter Roberson wrote:
In article <dn************@news.flash-gordon.me.uk>,
Flash Gordon <sp**@flash-gordon.me.ukwrote:
>Asbjørn Sæbø wrote, On 09/01/08 21:37:
>>Ben Pfaff <bl*@cs.stanford.eduwrites:
>>>Why are you replacing functions with macros? It sounds like
functions are more appropriate for this use case.
>>Indeed they are, except for the fact that I am working on an embedded
platform and having "multiple call" problems, with functions being
called both from main() and from interrupts. Replacing functions with
macros is one step towards one way of solving this.
>It is a truly horrible way of solving it in my opinion. Better ways
would include:
Making the functions safely re-entrant
Making the functions inline if your compiler supports this

As the poster mentioned in another part of this thread that his
embedded system has no stack, my *speculation* was that it does not
have "return addresses" for functions, and the compiler is doing
a static branch to the function and static return -- which would
only allow each function to be called once. (Which doesn't explain
how the standard library would work, but since it is an embedded
system at least the poster would not have I/O portion of the
standard library to be concerned with.)
Typically on small embedded processors, there is a small stack for return
addresses, but it is not feasible or possible to use for data storage.
Applications on some small processors are constrained by the maximum stack
size, affecting design strategy.
If this speculation were correct, it would be consistant with
"local variables" being possible if the compiler in question
ended up allocating the "local variables" at (possibly overlapping)
fixed addresses.
Yes, that is typical for these small systems. Some compilers will generate
reentrant code, as an option, with significant additional overhead, many
simply don't support recursive calls. Linkers determine how to overlap RAM
based on the calling tree. These systems needs hints when function
pointers are used.

The earlier suggestions of using multiple copies of a function is often the
best approach. On one system, I defined a function body in a single macro,
then instantiated it within two separate functions. Another approach is to
write a single copy of a static function and include it in multiple
source files. These approaches aren't elegant, but does the job.

--
Thad
Jan 10 '08 #8
Mark Bluemel wrote:
Asbjørn Sæbø wrote:
It's usually recommended to use do { } while(0) or some
similar hackery, so you can add ";" - see q10.4 in
http://www.c-faq.com
Nice technique, thanks!

But, can I just add ";" ?
Jan 11 '08 #9
Nickolai Leschov wrote:
Mark Bluemel wrote:
>Asbjørn Sæbø wrote:
It's usually recommended to use do { } while(0) or some
similar hackery, so you can add ";" - see q10.4 in
http://www.c-faq.com

Nice technique, thanks!

But, can I just add ";" ?
I don't understand your question. The FAQ explains what the issue is
and why this technique is needed.

What are you trying to do?
Jan 11 '08 #10

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

0
by: Jan | last post by:
I store sql-commands in a database table. In the first step I get the sql command out of the database table with embedded sql. In the second step I try to execute the command, which i got from the...
5
by: Dan C Douglas | last post by:
I have just installed VS.NET 2003 on my computer. I have a project that I have been developing on VS.NET 2002. I haven't upgraded this project to VS.NET 2003 yet and I am still developing it in...
7
by: Jim Carlock | last post by:
Does a SELECT element (listbox) need to be inside a FORM element? The code I'm playing with: <?xml version="1.0" encoding="utf-8"?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"...
59
by: Pierre Quentel | last post by:
Hi all, In some program I was testing if a variable was a boolean, with this test : if v in My script didn't work in some cases and I eventually found that for v = 0 the test returned True ...
13
by: Noa | last post by:
Hi I have a page that looks like that: <form name="kuku1" action ="anotherpage.html" > <input name="name"> <input name="kuku2"> </form> As far as i know, "getAttribute" should return a...
9
by: Klaus Johannes Rusch | last post by:
IE7 returns "unknown" instead of "undefined" when querying the type of an unknown property of an object, for example document.write(typeof window.missingproperty); Has "unknown" been defined...
2
by: Phillip Vong | last post by:
VS2005 on a SQL 2000 Please help me understand how to fix this problem. In SQL, a column is assigned Data Type of nvarchar(250). In each row, the value looks like this. FirstName LastName...
0
by: bolinc | last post by:
Can someone tell me why this isn't working? <Script language="JavaScript"><!--// var bJavaEnabled = Boolean(clientInformation.javaEnabled()); if (bJavaEnabled){ document.write('<form...
0
by: DolphinDB | last post by:
Tired of spending countless mintues downsampling your data? Look no further! In this article, you’ll learn how to efficiently downsample 6.48 billion high-frequency records to 61 million...
0
by: ryjfgjl | last post by:
ExcelToDatabase: batch import excel into database automatically...
1
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, we are pleased to welcome back...
0
by: Vimpel783 | last post by:
Hello! Guys, I found this code on the Internet, but I need to modify it a little. It works well, the problem is this: Data is sent from only one cell, in this case B5, but it is necessary that data...
0
by: jfyes | last post by:
As a hardware engineer, after seeing that CEIWEI recently released a new tool for Modbus RTU Over TCP/UDP filtering and monitoring, I actively went to its official website to take a look. It turned...
1
by: PapaRatzi | last post by:
Hello, I am teaching myself MS Access forms design and Visual Basic. I've created a table to capture a list of Top 30 singles and forms to capture new entries. The final step is a form (unbound)...
1
by: CloudSolutions | last post by:
Introduction: For many beginners and individual users, requiring a credit card and email registration may pose a barrier when starting to use cloud servers. However, some cloud server providers now...
0
by: af34tf | last post by:
Hi Guys, I have a domain whose name is BytesLimited.com, and I want to sell it. Does anyone know about platforms that allow me to list my domain in auction for free. Thank you
0
by: Faith0G | last post by:
I am starting a new it consulting business and it's been a while since I setup a new website. Is wordpress still the best web based software for hosting a 5 page website? The webpages will be...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.