Is it true that C macros are unsafe when combined with side effects even if
they are "clean" e.g. could
foo_macro(++c);
execute "++c" multiple times even if foo_macro is "clean"? I have always
thought that "clean" macros (i.e. macros where all parameters are
surrounded by parentheses in the definition) do not have this problem...
I am wondering because I have just looked up putc() in a reference, and it
says that it is unsafe if the "passed" value has a side effect, and I assume
standard macros are "clean"... 20 3357
>>>>"c" == copx <co**@gazeta.plwrites:
cIs it true that C macros are unsafe when combined with side
ceffects even if they are "clean" e.g. could
cfoo_macro(++c);
#define foo_macro(x) (x)*(x)
Whoops.
Charlton
--
Charlton Wilbur cw*****@chromatico.net
copx wrote:
Is it true that C macros are unsafe when combined with side effects even if
they are "clean" e.g. could
foo_macro(++c);
execute "++c" multiple times even if foo_macro is "clean"? I have always
thought that "clean" macros (i.e. macros where all parameters are
surrounded by parentheses in the definition) do not have this problem...
I am wondering because I have just looked up putc() in a reference, and it
says that it is unsafe if the "passed" value has a side effect, and I assume
standard macros are "clean"...
Your reference is correct, and "clean" macros can evaluate their
arguments multiple times. As a simple example, if you have
#define foo_macro(x) ((x) * (x))
then foo_macro's arguments are fully parenthesised, but foo_macro(++c)
will still expand to ((++c) * (++c)).
For most standard library functions, it is required that if they are
also implemented as a macro, that that macro evaluates each argument
exactly once. putc is an exception.
copx said:
Is it true that C macros are unsafe
Not if written correctly and used correctly.
when combined with side effects even if they are "clean" e.g. could
foo_macro(++c);
execute "++c" multiple times even if foo_macro is "clean"?
That is not a widely-used term for describing macros. (Translation: it's
the first time I have ever seen it.)
I have
always
thought that "clean" macros (i.e. macros where all parameters are
surrounded by parentheses in the definition) do not have this
problem...
You thought wrong.
I am wondering because I have just looked up putc() in a reference,
and it says that it is unsafe if the "passed" value has a side effect,
Your reference says wrong. The putc function, if implemented as a macro,
may evaluate the stream more than once, but *not* the character. And
you're hardly likely to call it as putc('\n', fp++), I trust?
and I assume standard macros are "clean"...
Why?
--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999 http://www.cpax.org.uk
email: rjh at the above domain, - www.
Richard Heathfield wrote:
copx said:
I am wondering because I have just looked up putc() in a reference,
and it says that it is unsafe if the "passed" value has a side effect,
Your reference says wrong. The putc function, if implemented as a macro,
may evaluate the stream more than once, but *not* the character.
That's a useful clarification, but it doesn't mean the reference is
wrong.
Richard Heathfield wrote On 05/04/07 12:34,:
copx said:
>>[...] "clean" macros (i.e. macros where all parameters are surrounded by parentheses in the definition) [...]
and I assume standard macros are "clean"...
Why?
Perhaps because of the Standard? 6.10.8 lists the
values of the predefined macros, and all are "clean."
7.1.2p5 requires "cleanliness" of all object-like macros
defined in the standard headers, and 7.1.4p2 does the same
for function-like macros that implement standard library
functions. What remains are the dribs and drabs like
va_start() and setjmp(); do you find them "unclean" (in
the O.P.'s sense, that is)?
-- Er*********@sun.com
In article <gP******************************@bt.com>,
Richard Heathfield <rj*@see.sig.invalidwrote:
>copx said:
>Is it true that C macros are unsafe
Not if written correctly and used correctly.
It's worth noting, though, that they're one of the easier parts of the
language to get wrong unintentionally, and it's sometimes easy to convert
correct use into incorrect use without realizing it, even if you do know
what you're doing.
If you compare programming in C to running with scissors, a lot of code
that uses macros ends up being at the pointy end of the scissors.
dave
(runs around the pool with scissors)
--
Dave Vandervies dj******@csclub.uwaterloo.ca
C is for people who run with scissors on a daily basis without cutting
themselves, because they know how to be careful around sharp tools.
--Richard Heathfield in comp.lang.c
copx wrote:
Is it true that C macros are unsafe when combined with side effects
even if they are "clean" e.g. could
foo_macro(++c);
execute "++c" multiple times even if foo_macro is "clean"?
Yes.
I have
always
thought that "clean" macros (i.e. macros where all parameters are
surrounded by parentheses in the definition) do not have this
problem...
Because macros are essentially a form of text substitution, the
parentheses in a macro definition can not influence how often an
argument gets evaluated.
The parentheses around macro arguments are needed to ensure that the
parser always interprets the complete argument as a single expression.
For example, take these two macros:
#define HALVE(x) x/2
#define DIVIDE_BY_TWO(x) (x)/2
When you use them like this:
y = HALVE(3+1);
z = DIVIDE_BY_TWO(3+1);
the preprocessor will replace the macros, yielding:
y = 3+1/2;
z = (3+1)/2;
Do you see the difference between the two statements?
>
I am wondering because I have just looked up putc() in a reference,
and it says that it is unsafe if the "passed" value has a side effect,
and I assume standard macros are "clean"...
Bart v Ingen Schenau
--
a.c.l.l.c-c++ FAQ: http://www.comeaucomputing.com/learn/faq
c.l.c FAQ: http://www.eskimo.com/~scs/C-faq/top.html
c.l.c++ FAQ: http://www.parashift.com/c++-faq-lite/
"Bart van Ingen Schenau" <ba**@ingen.ddns.infoschrieb im Newsbeitrag
news:60****************@ingen.ddns.info...
copx wrote:
>Is it true that C macros are unsafe when combined with side effects even if they are "clean" e.g. could
foo_macro(++c);
execute "++c" multiple times even if foo_macro is "clean"?
Yes.
>I have always thought that "clean" macros (i.e. macros where all parameters are surrounded by parentheses in the definition) do not have this problem...
Because macros are essentially a form of text substitution, the
parentheses in a macro definition can not influence how often an
argument gets evaluated.
The parentheses around macro arguments are needed to ensure that the
parser always interprets the complete argument as a single expression.
For example, take these two macros:
#define HALVE(x) x/2
#define DIVIDE_BY_TWO(x) (x)/2
When you use them like this:
y = HALVE(3+1);
z = DIVIDE_BY_TWO(3+1);
the preprocessor will replace the macros, yielding:
y = 3+1/2;
z = (3+1)/2;
Do you see the difference between the two statements?
[snip]
Yes, I remember that much of kindergarten math ;)
Thanks everyone.
"Harald van D?k" <tr*****@gmail.comwrote in message
news:11**********************@c35g2000hsg.googlegr oups.com...
copx wrote:
>Is it true that C macros are unsafe when combined with side effects even if they are "clean" e.g. could
foo_macro(++c);
execute "++c" multiple times even if foo_macro is "clean"? I have always thought that "clean" macros (i.e. macros where all parameters are surrounded by parentheses in the definition) do not have this problem...
I am wondering because I have just looked up putc() in a reference, and it says that it is unsafe if the "passed" value has a side effect, and I assume standard macros are "clean"...
Your reference is correct, and "clean" macros can evaluate their
arguments multiple times. As a simple example, if you have
#define foo_macro(x) ((x) * (x))
then foo_macro's arguments are fully parenthesised, but foo_macro(++c)
will still expand to ((++c) * (++c)).
For most standard library functions, it is required that if they are
also implemented as a macro, that that macro evaluates each argument
exactly once. putc is an exception.
Not "exactly once", but "at most once". It is quite legitimate for
some argument to not be evaluated at all.
--
Fred L. Kleinschmidt
Boeing Associate Technical Fellow
Aero Stability and Controls Computing
Eric Sosman said:
Richard Heathfield wrote On 05/04/07 12:34,:
>copx said:
>>>[...] "clean" macros (i.e. macros where all parameters are surrounded by parentheses in the definition) [...]
and I assume standard macros are "clean"...
Why?
Perhaps because of the Standard? 6.10.8 lists the
values of the predefined macros, and all are "clean."
Those are macros such as __FILE__, and they don't take parameters, so I
don't see why they're relevant.
7.1.2p5 requires "cleanliness" of all object-like macros
defined in the standard headers,
Sure.
and 7.1.4p2 does the same
for function-like macros that implement standard library
functions.
7.1.4p2 (of C99 - there is no such paragraph in C89) says:
2 Provided that a library function can be declared without reference to
any type defined in a header, it is also permissible to declare the
function and use it without including its associated header.
I don't see how this says anything about parenthetical protection for a
function-like macro's arguments.
What remains are the dribs and drabs like
va_start() and setjmp(); do you find them "unclean" (in
the O.P.'s sense, that is)?
As far as I am aware, that depends on the implementation.
--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999 http://www.cpax.org.uk
email: rjh at the above domain, - www.
Harald van D?k said:
Richard Heathfield wrote:
>copx said:
I am wondering because I have just looked up putc() in a reference,
and it says that it is unsafe if the "passed" value has a side
effect,
Your reference says wrong. The putc function, if implemented as a macro, may evaluate the stream more than once, but *not* the character.
That's a useful clarification, but it doesn't mean the reference is
wrong.
It's wrong because of 4.1.6 (C89) and 7.1.4(1) (C99):
"Any invocation of a library function that is implemented as
a macro shall expand to code that evaluates each of its arguments
exactly once, fully protected by parentheses where necessary, so it is
generally safe to use arbitrary expressions as arguments."
....and that means that there is an apparent contradiction between the
above text and the description of putc in 4.9.7.8 (C89) and 7.19.7.8
(C99). Has this been the subject of any DRs?
--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999 http://www.cpax.org.uk
email: rjh at the above domain, - www.
Dave Vandervies said:
<snip>
If you compare programming in C to running with scissors, a lot of
code that uses macros ends up being at the pointy end of the scissors.
Aye - it's snipped out, and discarded. :-)
--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999 http://www.cpax.org.uk
email: rjh at the above domain, - www.
Fred Kleinschmidt wrote On 05/04/07 14:20,:
"Harald van D?k" <tr*****@gmail.comwrote
>> For most standard library functions, it is required that if they are also implemented as a macro, that that macro evaluates each argument exactly once. putc is an exception.
Not "exactly once", but "at most once". It is quite legitimate for
some argument to not be evaluated at all.
Not "at most once," but "exactly once," and it is
ILlegitimate to omit evaluating an argument. 7.1.4p1:
[...] Any invocation of a library function that is
implemented as a macro shall expand to code that
evaluates each of its arguments exactly once, fully
protected by parentheses where necessary, [...]
-- Er*********@sun.com
Richard Heathfield wrote On 05/04/07 14:55,:
Eric Sosman said:
>>Richard Heathfield wrote On 05/04/07 12:34,:
>>>copx said:
[...] "clean" macros (i.e. macros where all parameters are surrounded by parentheses in the definition) [...]
and I assume standard macros are "clean"...
Why?
Perhaps because of the Standard? [...] and 7.1.4p2 does the same for function-like macros that implement standard library functions.
7.1.4p2 (of C99 - there is no such paragraph in C89) says:
2 Provided that a library function can be declared without reference to
any type defined in a header, it is also permissible to declare the
function and use it without including its associated header.
I don't see how this says anything about parenthetical protection for a
function-like macro's arguments.
My error: should have been p1, not p2.
"[...] Any invocation of a library function that
is ipmlemented as a macro shall expand to code
that evaluates each of its arguments exactly once,
fully protected by parentheses where necessary [...]"
>>What remains are the dribs and drabs like va_start() and setjmp(); do you find them "unclean" (in the O.P.'s sense, that is)?
As far as I am aware, that depends on the implementation.
Perhaps you're right. I shall henceforth avoid
code like
va_list array[10], *ap = array;
va_start (ap + 5, parmN);
.... even though it'll cramp my style.
-- Er*********@sun.com
Richard Heathfield <rj*@see.sig.invalidwrites:
Harald van D?k said:
>Richard Heathfield wrote:
>>copx said: I am wondering because I have just looked up putc() in a reference, and it says that it is unsafe if the "passed" value has a side effect,
Your reference says wrong. The putc function, if implemented as a macro, may evaluate the stream more than once, but *not* the character.
That's a useful clarification, but it doesn't mean the reference is wrong.
It's wrong because of 4.1.6 (C89) and 7.1.4(1) (C99):
"Any invocation of a library function that is implemented as
a macro shall expand to code that evaluates each of its arguments
exactly once, fully protected by parentheses where necessary, so it is
generally safe to use arbitrary expressions as arguments."
...and that means that there is an apparent contradiction between the
above text and the description of putc in 4.9.7.8 (C89) and 7.19.7.8
(C99). Has this been the subject of any DRs?
There's no need for a DR. Go back to the beginning of paragraph C99
7.1.4p1:
Each of the following statements applies unless explicitly stated
otherwise in the detailed descriptions that follow:
[...]
The description of putc() explicitly states otherwise.
--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <* <http://users.sdsc.edu/~kst>
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
Richard Heathfield wrote:
>
.... snip ...
>
It's wrong because of 4.1.6 (C89) and 7.1.4(1) (C99):
"Any invocation of a library function that is implemented as
a macro shall expand to code that evaluates each of its arguments
exactly once, fully protected by parentheses where necessary, so
it is generally safe to use arbitrary expressions as arguments."
...and that means that there is an apparent contradiction between
the above text and the description of putc in 4.9.7.8 (C89) and
7.19.7.8 (C99). Has this been the subject of any DRs?
Note para. 2 below.
N869:
7.19.7.8 The putc function
Synopsis
[#1]
#include <stdio.h>
int putc(int c, FILE *stream);
Description
[#2] The putc function is equivalent to fputc, except that
if it is implemented as a macro, it may evaluate stream more
than once, so that argument should never be an expression
with side effects.
Returns
[#3] The putc function returns the character written. If a
write error occurs, the error indicator for the stream is
set and putc returns EOF.
--
<http://www.cs.auckland.ac.nz/~pgut001/pubs/vista_cost.txt>
<http://www.securityfocus.com/columnists/423>
<http://www.aaxnet.com/editor/edit043.html>
<http://kadaitcha.cx/vista/dogsbreakfast/index.html>
cbfalconer at maineline dot net
--
Posted via a free Usenet account from http://www.teranews.com
Richard Heathfield <rj*@see.sig.invalidwrote:
>
...and that means that there is an apparent contradiction between the
above text and the description of putc in 4.9.7.8 (C89) and 7.19.7.8
(C99). Has this been the subject of any DRs?
No, because the very first sentence of 4.1.6/7.1.4 resolves it:
Each of the following statements applies unless explicitly
stated otherwise in the detailed descriptions that follow:
So the explicit license in the description of putc takes precedence.
-Larry Jones
The hardest part for us avant-garde post-modern artists is
deciding whether or not to embrace commercialism. -- Calvin
Keith Thompson said:
<snip>
There's no need for a DR. Go back to the beginning of paragraph C99
7.1.4p1:
Each of the following statements applies unless explicitly stated
otherwise in the detailed descriptions that follow:
[...]
The description of putc() explicitly states otherwise.
No fair! Expecting me to /read/ the thing, as opposed to merely
searching it...
--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999 http://www.cpax.org.uk
email: rjh at the above domain, - www.
CBFalconer said:
Richard Heathfield wrote:
>> ...and that means that there is an apparent contradiction between the above text and the description of putc in 4.9.7.8 (C89) and 7.19.7.8 (C99). Has this been the subject of any DRs?
Note para. 2 below.
I was wrong, but that isn't why I was wrong.
--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999 http://www.cpax.org.uk
email: rjh at the above domain, - www.
Richard Heathfield wrote:
>
Harald van D?k said:
Richard Heathfield wrote:
copx said:
I am wondering because I have just looked up putc() in a reference,
and it says that it is unsafe if the "passed" value has a side
effect,
Your reference says wrong. The putc function, if implemented as a
macro, may evaluate the stream more than once, but *not* the
character.
That's a useful clarification, but it doesn't mean the reference is
wrong.
It's wrong because of 4.1.6 (C89) and 7.1.4(1) (C99):
"Any invocation of a library function that is implemented as
a macro shall expand to code that evaluates each of its arguments
exactly once, fully protected by parentheses where necessary, so it is
generally safe to use arbitrary expressions as arguments."
...and that means that there is an apparent contradiction between the
above text and the description of putc in 4.9.7.8 (C89) and 7.19.7.8
(C99). Has this been the subject of any DRs?
There's two exceptions.
putc is one, getc is the other.
--
pete This thread has been closed and replies have been disabled. Please start a new discussion. Similar topics
by: mike420 |
last post by:
Tayss wrote:
>
> app = wxPySimpleApp()
> frame = MainWindow(None, -1, "A window")
> frame.Show(True)
> app.MainLoop()
>
Why do you need a macro for that? Why don't you just write
|
by: Michael Winter |
last post by:
In a recent post ("About C error" by Victor, 21 Sep 2003), comments were
made about the poster's use of macros. What I would like to know is why
they are considered bad? I'm not referring to...
|
by: Generic Usenet Account |
last post by:
I have written a small macro that provides the relative offset of any
field within a structure. Here it goes:
#define RELATIVE_OFFSET(a,b) \
{ \
cout << "The relative offset of the " \
<<...
|
by: Niklaus |
last post by:
This is one of the posts that i got.
------------------------------
A "side effect" of an operation is something that
*happens*, not something that *is produced*. Examples:
In the expression...
|
by: Andrew Arro |
last post by:
is it possible to make smth like a loop of macroses? i.e. i want some
macros to be called X times, all that on the PREPROCESSOR lever
i was trying smth like
#define vv_0 100
#define vv_1...
|
by: Robert Seacord |
last post by:
When writing C99 code is a reasonable recommendation to use inline
functions instead of macros?
What sort of things is it still reasonable to do using macros? For
example, is it reasonable to...
|
by: Cephalobus_alienus |
last post by:
Hello,
I know that macros are evil, but I recently came across a problem
that I couldn't figure out how to solve with templates.
I wanted to create a set of singleton event objects, and wrote...
|
by: Floobar |
last post by:
Macros sure can be fun -- and profitable. This actually worked -- it
might work for any of you guys too.
The trick is to make your code look sensible, but be actually very hard
to modify without...
|
by: prashant.khade1623 |
last post by:
HI All,
I know the clear distinction between macro and function.
I know that macro will speed up the program and using function will
reduce the size.
But how do we know when to use macro...
|
by: Sonnysonu |
last post by:
This is the data of csv file
1 2 3
1 2 3
1 2 3
1 2 3
2 3
2 3
3
the lengths should be different i have to store the data by column-wise with in the specific length.
suppose the i have to...
|
by: Hystou |
last post by:
There are some requirements for setting up RAID:
1. The motherboard and BIOS support RAID configuration.
2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
|
by: marktang |
last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
|
by: jinu1996 |
last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
|
by: Hystou |
last post by:
Overview:
Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
|
by: tracyyun |
last post by:
Dear forum friends,
With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
|
by: isladogs |
last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM).
In this session, we are pleased to welcome a new...
|
by: TSSRALBI |
last post by:
Hello
I'm a network technician in training and I need your help.
I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs.
The...
|
by: 6302768590 |
last post by:
Hai team
i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated ...
| |