473,511 Members | 15,630 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Anonymous functions in C.

Gnu C features some interesting extensions, among others
compound statements that return a value. For instance:

({ int y = foo(); int z;
if (y>0) z = y; else z=-y;
z;
})
A block enclosed by braces can appear within parentheses
to form a block that "returns" a value. This is handy
in some macros, or in other applications.

Actually this construct is nothing more (and nothing less)
than anonymous functions.

Anonymous functions could be really handy in call to qsort,
for instance, where just writing an expression could allow
the compiler to expand the anonymous function at each point of
call (as an inline function) within the qsort algorithm.

This, and other extensions are published in a document
"Potential Extnsions for Inclusion in a revision of
ISO/EIC 98/99" available at

http://www.open-std.org/jtc1/sc22/wg...docs/n1229.pdf

That is the official standard site.

Other Gnu extensions are mentioned in that document, like typeof
for instance, an extension that also lcc-win32 implements.
jacob
Apr 21 '07 #1
60 5394
jacob navia <ja***@jacob.remcomp.frwrites:
Gnu C features some interesting extensions, among others
compound statements that return a value. For instance:

({ int y = foo(); int z;
if (y>0) z = y; else z=-y;
z;
})
A block enclosed by braces can appear within parentheses
to form a block that "returns" a value. This is handy
in some macros, or in other applications.

Actually this construct is nothing more (and nothing less)
than anonymous functions.

Anonymous functions could be really handy in call to qsort,
for instance, where just writing an expression could allow
the compiler to expand the anonymous function at each point of
call (as an inline function) within the qsort algorithm.
No, GNU C's compound statements are not anonymous functions, because
they don't take arguments. How would you write a call to qsort()
using a compound statement in place of the compar argument? How would
the compound statement obtain the values to be compared?

I suppose GNU C's compound statements could be extended to act like
anonymous functions, but that's not what's being proposed.
This, and other extensions are published in a document
"Potential Extnsions for Inclusion in a revision of
ISO/EIC 98/99" available at

http://www.open-std.org/jtc1/sc22/wg...docs/n1229.pdf

That is the official standard site.

Other Gnu extensions are mentioned in that document, like typeof
for instance, an extension that also lcc-win32 implements.
This would be more appropriate for comp.std.c. I have some comments
on the document; if you post there, I'll reply.

--
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"
Apr 21 '07 #2
jacob navia said:

<snip>
Other Gnu extensions are mentioned in that document, like typeof
for instance, an extension that also lcc-win32 implements.
If your articles were not so often thinly-veiled advertisements for your
product, perhaps people might take them a little more seriously.

Note that C does not have anonymous functions. If you want to add
anonymous functions to standard C, comp.std.c is the appropriate
newsgroup in which to suggest it.

--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999
http://www.cpax.org.uk
email: rjh at the above domain, - www.
Apr 21 '07 #3
In article <-Z******************************@bt.com>,
Richard Heathfield <rj*@see.sig.invalidwrote:
>Note that C does not have anonymous functions. If you want to add
anonymous functions to standard C, comp.std.c is the appropriate
newsgroup in which to suggest it.
But if you want to discuss what anonymous functions might be like, how
they would fit in with the rest of C and so on, without considering
whether it is appropriate to standardise them, then comp.lang.c seems
a reasonable choice.

-- Richard

--
"Consideration shall be given to the need for as many as 32 characters
in some alphabets" - X3.4, 1963.
Apr 21 '07 #4
In article <ln************@nuthaus.mib.org>,
Keith Thompson <ks***@mib.orgwrote:
>No, GNU C's compound statements are not anonymous functions, because
they don't take arguments. How would you write a call to qsort()
using a compound statement in place of the compar argument? How would
the compound statement obtain the values to be compared?
>I suppose GNU C's compound statements could be extended to act like
anonymous functions, but that's not what's being proposed.
Anonymous functions are almost always going to be *nested* functions,
which opens the whole can of worms concerning non-local variables.
Can these functions refer to, and modify, variables in the containing
function? What happens if you return the functions to outside the
scope of the containing function?

GNU C already has nested (non-anonymous) functions, so they must have
addressed these questions.

-- Richard
--
"Consideration shall be given to the need for as many as 32 characters
in some alphabets" - X3.4, 1963.
Apr 21 '07 #5
Richard Tobin said:
In article <-Z******************************@bt.com>,
Richard Heathfield <rj*@see.sig.invalidwrote:
>>Note that C does not have anonymous functions. If you want to add
anonymous functions to standard C, comp.std.c is the appropriate
newsgroup in which to suggest it.

But if you want to discuss what anonymous functions might be like, how
they would fit in with the rest of C and so on, without considering
whether it is appropriate to standardise them, then comp.lang.c seems
a reasonable choice.
Would I be right in thinking that the GNU syntax for assigning a value
to a compound statement could be adopted (and whether that's desirable
or not is not a question I am addressing here) without actually
breaking any existing code?

For the record, AIUI the GNU syntax for this is that the compound
statement ends in a single expression whose value is taken as the value
of the whole statement, as the following code fragment (which is not
valid C) illustrates:

double area = { double a = r * r * pi; a; }

That's a lousy example, though, because it's so pointless. I spent a few
moments trying to think up a genuine use for these things, and didn't
manage it. Of course, that doesn't mean there isn't one.

--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999
http://www.cpax.org.uk
email: rjh at the above domain, - www.
Apr 21 '07 #6
In article <uI******************************@bt.com>,
Richard Heathfield <rj*@see.sig.invalidwrote:
>Would I be right in thinking that the GNU syntax for assigning a value
to a compound statement could be adopted (and whether that's desirable
or not is not a question I am addressing here) without actually
breaking any existing code?
As far as I'm aware.
>double area = { double a = r * r * pi; a; }

That's a lousy example, though, because it's so pointless. I spent a few
moments trying to think up a genuine use for these things, and didn't
manage it. Of course, that doesn't mean there isn't one.
I imagine that one reason why uses of this are not obvious is just
that in C (unlike Lisp) it's not traditional to write things as nested
multi-line expressions, and that in turn is because at present you
can't generally do it. Allowing compound statements to return values
(and of course allowing them to appear in expressions) would make C
into an "expression language", and it would then be able to adopt the
idioms of such languages.

Without going that far, one obvious use is in macros, since it allows
you introduce new variables in the macro expansion. Of course, you
then run into the question of what's a safe name for those variables
(in Lisp, you traditionally use gensym to generate a variable name,
but that requires a more powerful macro language). Many of the macro
uses can be more cleanly solved with inline functions, but others
depend on being able to access variables that aren't arguments to the
function or macro.

-- Richard

--
"Consideration shall be given to the need for as many as 32 characters
in some alphabets" - X3.4, 1963.
Apr 21 '07 #7
ri*****@cogsci.ed.ac.uk (Richard Tobin) writes:
[...]
Without going that far, one obvious use is in macros, since it allows
you introduce new variables in the macro expansion. Of course, you
then run into the question of what's a safe name for those variables
(in Lisp, you traditionally use gensym to generate a variable name,
but that requires a more powerful macro language). Many of the macro
uses can be more cleanly solved with inline functions, but others
depend on being able to access variables that aren't arguments to the
function or macro.
I don't think variable names are an issue. A compound statement
creates a new scope, even if it's the result of a macro expansion.

--
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"
Apr 21 '07 #8
Keith Thompson wrote:
ri*****@cogsci.ed.ac.uk (Richard Tobin) writes:
[...]
Without going that far, one obvious use is in macros, since it allows
you introduce new variables in the macro expansion. Of course, you
then run into the question of what's a safe name for those variables
(in Lisp, you traditionally use gensym to generate a variable name,
but that requires a more powerful macro language). Many of the macro
uses can be more cleanly solved with inline functions, but others
depend on being able to access variables that aren't arguments to the
function or macro.

I don't think variable names are an issue. A compound statement
creates a new scope, even if it's the result of a macro expansion.
#define my_abs(x) ({ int y = x; y 0 ? y : -y; })

would fail if called as my_abs(y).

Apr 21 '07 #9
In article <ln************@nuthaus.mib.org>,
Keith Thompson <ks***@mib.orgwrote:
>I don't think variable names are an issue. A compound statement
creates a new scope, even if it's the result of a macro expansion.
But because names in a new scope can shadow outer ones, you have the
problem of inadvertent "variable capture", for example:

#define macro(x) {int t = (x)*2; ...}
...
int t;
macro(t+4);

There are obvious conventions to reduce the problem, but these are
likely to fail if you might have nested macro calls.

-- Richard
--
"Consideration shall be given to the need for as many as 32 characters
in some alphabets" - X3.4, 1963.
Apr 21 '07 #10
Richard Tobin a écrit :
In article <ln************@nuthaus.mib.org>,
Keith Thompson <ks***@mib.orgwrote:
>No, GNU C's compound statements are not anonymous functions, because
they don't take arguments. How would you write a call to qsort()
using a compound statement in place of the compar argument? How would
the compound statement obtain the values to be compared?
The expressions take arguments from the local context, as far as the
implementation of gNU is concerned.

This is not fully anonymous functions but a step in that direction.
>I suppose GNU C's compound statements could be extended to act like
anonymous functions, but that's not what's being proposed.
Yes, it is not, but could be.
>
Anonymous functions are almost always going to be *nested* functions,
which opens the whole can of worms concerning non-local variables.
Can these functions refer to, and modify, variables in the containing
function? What happens if you return the functions to outside the
scope of the containing function?

GNU C already has nested (non-anonymous) functions, so they must have
addressed these questions.
As far as I remember their implementation is similar to pascal.
Nested functions take the environment where they are defined.
Apr 21 '07 #11
Richard Heathfield <rj*@see.sig.invalidwrites:
For the record, AIUI the GNU syntax for this is that the compound
statement ends in a single expression whose value is taken as the value
of the whole statement, as the following code fragment (which is not
valid C) illustrates:

double area = { double a = r * r * pi; a; }

That's a lousy example, though, because it's so pointless. I spent a few
moments trying to think up a genuine use for these things, and didn't
manage it. Of course, that doesn't mean there isn't one.
AFAIK, those statements where introduced to allow #defining /inline/
functions, like:

#define max(a, b) ({ int _a = (a), _b = (b); _a < _b ? _b : _a; })

--
Best regards, _ _
.o. | Liege of Serenly Enlightened Majesty of o' \,=./ `o
..o | Computer Science, Michal "mina86" Nazarewicz (o o)
ooo +--<mina86*tlen.pl>---<jid:mina86*chrome.pl>--ooO--(_)--Ooo--
Apr 21 '07 #12
Michal Nazarewicz said:
Richard Heathfield <rj*@see.sig.invalidwrites:
>For the record, AIUI the GNU syntax for this is that the compound
statement ends in a single expression whose value is taken as the
value of the whole statement, as the following code fragment (which
is not valid C) illustrates:

double area = { double a = r * r * pi; a; }

That's a lousy example, though, because it's so pointless. I spent a
few moments trying to think up a genuine use for these things, and
didn't manage it. Of course, that doesn't mean there isn't one.

AFAIK, those statements where introduced to allow #defining /inline/
functions, like:

#define max(a, b) ({ int _a = (a), _b = (b); _a < _b ? _b : _a; })
Well, this is another lousy example (sorry, Michal!) because it can be
done so easily in standard C:

#define max(a, b) (((a) (b)) ? (a) : (b))

I'm sure this proposed new syntax must have a use, but I'm still
struggling to find one.

--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999
http://www.cpax.org.uk
email: rjh at the above domain, - www.
Apr 21 '07 #13
Richard Tobin a écrit :
In article <ln************@nuthaus.mib.org>,
Keith Thompson <ks***@mib.orgwrote:
>I don't think variable names are an issue. A compound statement
creates a new scope, even if it's the result of a macro expansion.

But because names in a new scope can shadow outer ones, you have the
problem of inadvertent "variable capture", for example:

#define macro(x) {int t = (x)*2; ...}
...
int t;
macro(t+4);

There are obvious conventions to reduce the problem, but these are
likely to fail if you might have nested macro calls.

-- Richard
There is only one solution:
make real anonymous functions with arguments, etc.

How would they look like in C?

Apr 21 '07 #14
Richard Heathfield a écrit :
>
Well, this is another lousy example (sorry, Michal!) because it can be
done so easily in standard C:

#define max(a, b) (((a) (b)) ? (a) : (b))

I'm sure this proposed new syntax must have a use, but I'm still
struggling to find one.
Your example evaluates at least one argument twice. The example with the
GNU syntax doesn't.

Please read the contributions in this same thread
Apr 21 '07 #15
>Richard Heathfield <rj*@see.sig.invalidwrites:
>>For the record, AIUI the GNU syntax for this is that the compound
statement ends in a single expression whose value is taken as the
value of the whole statement, as the following code fragment (which
is not valid C) illustrates:

double area = { double a = r * r * pi; a; }

That's a lousy example, though, because it's so pointless. I spent a
few moments trying to think up a genuine use for these things, and
didn't manage it. Of course, that doesn't mean there isn't one.
Michal Nazarewicz said:
>AFAIK, those statements where introduced to allow #defining /inline/
functions, like:

#define max(a, b) ({ int _a = (a), _b = (b); _a < _b ? _b : _a; })
Richard Heathfield <rj*@see.sig.invalidwrites:
Well, this is another lousy example (sorry, Michal!) because it can be
done so easily in standard C:

#define max(a, b) (((a) (b)) ? (a) : (b))
And what about:

int i = 1, j = 0;
int k = max(++i, j);

--
Best regards, _ _
.o. | Liege of Serenly Enlightened Majesty of o' \,=./ `o
..o | Computer Science, Michal "mina86" Nazarewicz (o o)
ooo +--<mina86*tlen.pl>---<jid:mina86*chrome.pl>--ooO--(_)--Ooo--
Apr 21 '07 #16
jacob.navia said:
Richard Heathfield a écrit :
>>
Well, this is another lousy example (sorry, Michal!) because it can
be done so easily in standard C:

#define max(a, b) (((a) (b)) ? (a) : (b))

I'm sure this proposed new syntax must have a use, but I'm still
struggling to find one.

Your example evaluates at least one argument twice. The example with
the GNU syntax doesn't.
That is certainly true, but irrelevant unless the caller is abusing the
preprocessor by using macro arguments which oughtn't to be evaluated
more than once. If the motivation for anonymous functions is simply to
make it possible to abuse the preprocessor in comfort, then I don't see
the value. No doubt there are better uses.

--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999
http://www.cpax.org.uk
email: rjh at the above domain, - www.
Apr 21 '07 #17
Michal Nazarewicz said:
>>Richard Heathfield <rj*@see.sig.invalidwrites:
For the record, AIUI the GNU syntax for this is that the compound
statement ends in a single expression whose value is taken as the
value of the whole statement, as the following code fragment (which
is not valid C) illustrates:

double area = { double a = r * r * pi; a; }

That's a lousy example, though, because it's so pointless. I spent
a few moments trying to think up a genuine use for these things,
and didn't manage it. Of course, that doesn't mean there isn't one.
>Michal Nazarewicz said:
>>AFAIK, those statements where introduced to allow #defining /inline/
functions, like:

#define max(a, b) ({ int _a = (a), _b = (b); _a < _b ? _b : _a; })

Richard Heathfield <rj*@see.sig.invalidwrites:
>Well, this is another lousy example (sorry, Michal!) because it can
be done so easily in standard C:

#define max(a, b) (((a) (b)) ? (a) : (b))

And what about:

int i = 1, j = 0;
int k = max(++i, j);
Understood (multiple eval), but frankly I wouldn't go adding an entire
new language feature just to make extra work for myself when I can
already write this as:

int i = 2, j = 0, k = 2;

and in any case, the C community already knows not to risk such
expressions as yours when using macros. Are we going to muddy the
waters by introducing a language feature which makes it okay sometimes,
provided you're careful in the #define?

I don't see that as a win.

--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999
http://www.cpax.org.uk
email: rjh at the above domain, - www.
Apr 21 '07 #18
>Richard Heathfield a écrit :
>>>
Well, this is another lousy example (sorry, Michal!) because it can
be done so easily in standard C:

#define max(a, b) (((a) (b)) ? (a) : (b))

I'm sure this proposed new syntax must have a use, but I'm still
struggling to find one.
jacob.navia said:
>Your example evaluates at least one argument twice. The example with
the GNU syntax doesn't.
Richard Heathfield <rj*@see.sig.invalidwrites:
That is certainly true, but irrelevant unless the caller is abusing the
preprocessor by using macro arguments which oughtn't to be evaluated
more than once.
AFAIK that was the reason this syntax was introduced in GCC (though I
may be wrong).
If the motivation for anonymous functions is simply to
make it possible to abuse the preprocessor in comfort, then I don't see
the value. No doubt there are better uses.
Certainly it wouldn't make sens to introduce anonymous functions just
to allow abusing preprocessor as we have inline functions in C99.

IMO there's not much use for them anyway. The only thing I can think
of is:

qsort(array, sizeof array / sizeof *array, sizeof *array,
({ some kind of strange syntax }));

and it's not like one uses callback functions every 10th line of code.

--
Best regards, _ _
.o. | Liege of Serenly Enlightened Majesty of o' \,=./ `o
..o | Computer Science, Michal "mina86" Nazarewicz (o o)
ooo +--<mina86*tlen.pl>---<jid:mina86*chrome.pl>--ooO--(_)--Ooo--
Apr 21 '07 #19
Michal Nazarewicz said:

<snip>
Certainly it wouldn't make sens to introduce anonymous functions just
to allow abusing preprocessor as we have inline functions in C99.
Agreed.
IMO there's not much use for them anyway. The only thing I can think
of is:

qsort(array, sizeof array / sizeof *array, sizeof *array,
({ some kind of strange syntax }));
Interesting. Perhaps something like this:

{ :formal parameter list: { body goes here } value; }
and it's not like one uses callback functions every 10th line of code.
Yeah, this does look like a solution looking for a problem.

--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999
http://www.cpax.org.uk
email: rjh at the above domain, - www.
Apr 21 '07 #20
Richard Tobin wrote:
In article <ln************@nuthaus.mib.org>,
Keith Thompson <ks***@mib.orgwrote:
>I don't think variable names are an issue. A compound statement
creates a new scope, even if it's the result of a macro expansion.

But because names in a new scope can shadow outer ones, you have the
problem of inadvertent "variable capture", for example:

#define macro(x) {int t = (x)*2; ...}
...
int t;
macro(t+4);

There are obvious conventions to reduce the problem, but these are
likely to fail if you might have nested macro calls.
Correct me if I'm wrong (it's been known to happen ...),
but I think there's no problem with the example shown. The
scope of the "inner" t begins at the end of its declarator
(6.2.1/7), and the initialization is part of the declarator
(6.7/1). Therefore, in the expanded `int t = (t + 4) * 2;'
the initializer's t refers to the "outer" variable, not to the
variable being initialized.

--
Eric Sosman
es*****@acm-dot-org.invalid
Apr 21 '07 #21
Eric Sosman wrote:
Richard Tobin wrote:
In article <ln************@nuthaus.mib.org>,
Keith Thompson <ks***@mib.orgwrote:
I don't think variable names are an issue. A compound statement
creates a new scope, even if it's the result of a macro expansion.
But because names in a new scope can shadow outer ones, you have the
problem of inadvertent "variable capture", for example:

#define macro(x) {int t = (x)*2; ...}
...
int t;
macro(t+4);

There are obvious conventions to reduce the problem, but these are
likely to fail if you might have nested macro calls.

Correct me if I'm wrong (it's been known to happen ...),
but I think there's no problem with the example shown. The
scope of the "inner" t begins at the end of its declarator
(6.2.1/7), and the initialization is part of the declarator
(6.7/1).
The initialization part is not part of the declarator. The grammar
(6.7/1) reads:

init-declarator:
declarator
declarator = initializer

The initializer is part of "init-declarator", which is a combination
of a declarator and an initializer. The initializer is not part of the
declarator itself.

Apr 21 '07 #22
Harald van Dijk wrote:
Eric Sosman wrote:
>Richard Tobin wrote:
>>In article <ln************@nuthaus.mib.org>,
Keith Thompson <ks***@mib.orgwrote:

I don't think variable names are an issue. A compound statement
creates a new scope, even if it's the result of a macro expansion.
But because names in a new scope can shadow outer ones, you have the
problem of inadvertent "variable capture", for example:

#define macro(x) {int t = (x)*2; ...}
...
int t;
macro(t+4);

There are obvious conventions to reduce the problem, but these are
likely to fail if you might have nested macro calls.
Correct me if I'm wrong (it's been known to happen ...),
but I think there's no problem with the example shown. The
scope of the "inner" t begins at the end of its declarator
(6.2.1/7), and the initialization is part of the declarator
(6.7/1).

The initialization part is not part of the declarator. The grammar
(6.7/1) reads:

init-declarator:
declarator
declarator = initializer

The initializer is part of "init-declarator", which is a combination
of a declarator and an initializer. The initializer is not part of the
declarator itself.
Thanks for the correction. The grammar seems clear enough,
but the wording in 6.7/6 seems unclear:

"[...] The init-declarator-list is a comma-separated
sequence of declarators, each of which may have [...]
an initializer [...]"

I was reading "have" as "incorporate" or "subsume," but in light
of the grammar I guess it must mean "be accompanied by."

--
Eric Sosman
es*****@acm-dot-org.invalid

Apr 21 '07 #23
Richard Heathfield a écrit :
Michal Nazarewicz said:
>>>Richard Heathfield <rj*@see.sig.invalidwrites:
For the record, AIUI the GNU syntax for this is that the compound
statement ends in a single expression whose value is taken as the
value of the whole statement, as the following code fragment (which
is not valid C) illustrates:
>
double area = { double a = r * r * pi; a; }
>
That's a lousy example, though, because it's so pointless. I spent
a few moments trying to think up a genuine use for these things,
and didn't manage it. Of course, that doesn't mean there isn't one.
Michal Nazarewicz said:
AFAIK, those statements where introduced to allow #defining /inline/
functions, like:

#define max(a, b) ({ int _a = (a), _b = (b); _a < _b ? _b : _a; })
Richard Heathfield <rj*@see.sig.invalidwrites:
>>Well, this is another lousy example (sorry, Michal!) because it can
be done so easily in standard C:

#define max(a, b) (((a) (b)) ? (a) : (b))
And what about:

int i = 1, j = 0;
int k = max(++i, j);

Understood (multiple eval), but frankly I wouldn't go adding an entire
new language feature just to make extra work for myself when I can
already write this as:

int i = 2, j = 0, k = 2;

and in any case, the C community already knows not to risk such
expressions as yours when using macros. Are we going to muddy the
waters by introducing a language feature which makes it okay sometimes,
provided you're careful in the #define?

I don't see that as a win.
As you may know, macros and function calls are not
easy to distinguish in C.

You HAVE TO KNOW that you are calling a macro and not a function.
You may know that, or you may not.

What is important for language coherence and transparency is that

foo(i++);

evaluates i only once if it is a macro or not.
Apr 21 '07 #24
Harald van Dijk <tr*****@gmail.comwrites:
Keith Thompson wrote:
>ri*****@cogsci.ed.ac.uk (Richard Tobin) writes:
[...]
Without going that far, one obvious use is in macros, since it allows
you introduce new variables in the macro expansion. Of course, you
then run into the question of what's a safe name for those variables
(in Lisp, you traditionally use gensym to generate a variable name,
but that requires a more powerful macro language). Many of the macro
uses can be more cleanly solved with inline functions, but others
depend on being able to access variables that aren't arguments to the
function or macro.

I don't think variable names are an issue. A compound statement
creates a new scope, even if it's the result of a macro expansion.

#define my_abs(x) ({ int y = x; y 0 ? y : -y; })

would fail if called as my_abs(y).
You're right.

--
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"
Apr 21 '07 #25
"jacob.navia" <ja***@jacob.remcomp.frwrites:
Richard Tobin a écrit :
>In article <ln************@nuthaus.mib.org>,
Keith Thompson <ks***@mib.orgwrote:
>>I don't think variable names are an issue. A compound statement
creates a new scope, even if it's the result of a macro expansion.
But because names in a new scope can shadow outer ones, you have the
problem of inadvertent "variable capture", for example:
#define macro(x) {int t = (x)*2; ...}
...
int t;
macro(t+4);
There are obvious conventions to reduce the problem, but these are
likely to fail if you might have nested macro calls.

There is only one solution:
make real anonymous functions with arguments, etc.
There is another solution: use ordinary functions (inline if you
like).
How would they look like in C?
No idea.

--
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"
Apr 21 '07 #26
jacob.navia said:

<snip>
As you may know, macros and function calls are not
easy to distinguish in C.
It is generally quite simple to find out, if you have decent tools, but
I agree that they are superficially similar in appearance.
You HAVE TO KNOW that you are calling a macro and not a function.
Yes, you do.
You may know that, or you may not.
If you don't, you need to find out.
What is important for language coherence and transparency is that

foo(i++);

evaluates i only once if it is a macro or not.
Nevertheless, the risk exists that it may be evaluated more than once,
and this is well-known within the community. Introducing this new
language feature will not eliminate the risk.

--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999
http://www.cpax.org.uk
email: rjh at the above domain, - www.
Apr 21 '07 #27
>>Michal Nazarewicz said:
>>>AFAIK, those statements where introduced to allow #defining /inline/
functions, like:

#define max(a, b) ({ int _a = (a), _b = (b); _a < _b ? _b : _a; })
>Richard Heathfield <rj*@see.sig.invalidwrites:
>>Well, this is another lousy example (sorry, Michal!) because it can
be done so easily in standard C:

#define max(a, b) (((a) (b)) ? (a) : (b))
Michal Nazarewicz said:
>int i = 1, j = 0;
int k = max(++i, j);
Richard Heathfield <rj*@see.sig.invalidwrites:
Understood (multiple eval), but frankly I wouldn't go adding an entire
new language feature just to make extra work for myself when I can
already write this as:

int i = 2, j = 0, k = 2;

and in any case, the C community already knows not to risk such
expressions as yours when using macros. Are we going to muddy the
waters by introducing a language feature which makes it okay sometimes,
provided you're careful in the #define?
I'm not saying we should add this feature. I'm explaining what's it
all about.

--
Best regards, _ _
.o. | Liege of Serenly Enlightened Majesty of o' \,=./ `o
..o | Computer Science, Michal "mina86" Nazarewicz (o o)
ooo +--<mina86*tlen.pl>---<jid:mina86*chrome.pl>--ooO--(_)--Ooo--
Apr 21 '07 #28
Richard Heathfield wrote:
jacob.navia said:

>>Richard Heathfield a écrit :
>>>Well, this is another lousy example (sorry, Michal!) because it can
be done so easily in standard C:

#define max(a, b) (((a) (b)) ? (a) : (b))

I'm sure this proposed new syntax must have a use, but I'm still
struggling to find one.

Your example evaluates at least one argument twice. The example with
the GNU syntax doesn't.


That is certainly true, but irrelevant unless the caller is abusing the
preprocessor by using macro arguments which oughtn't to be evaluated
more than once. If the motivation for anonymous functions is simply to
make it possible to abuse the preprocessor in comfort, then I don't see
the value. No doubt there are better uses.
Maybe they were introduced before inline functions? The only use I
could see where inline functions don't apply was as a form of generics
inside a macro. But as you say, the need for this can be avoided by not
abusing the preprocessor.

--
Ian Collins.
Apr 21 '07 #29
Richard Heathfield wrote:
Michal Nazarewicz said:
.... snip ...
>
>AFAIK, those statements where introduced to allow #defining
/inline/ functions, like:

#define max(a, b) ({int _a = (a), _b = (b); _a < _b ? _b : _a;})

Well, this is another lousy example (sorry, Michal!) because it
can be done so easily in standard C:

#define max(a, b) (((a) (b)) ? (a) : (b))
Doesn't work very well when a and/or b have side effects.

--
<http://www.cs.auckland.ac.nz/~pgut001/pubs/vista_cost.txt>
<http://www.securityfocus.com/columnists/423>
<http://www.aaxnet.com/editor/edit043.html>
cbfalconer at maineline.net
--
Posted via a free Usenet account from http://www.teranews.com

Apr 21 '07 #30
In article <f0***********@pc-news.cogsci.ed.ac.uk>,
Richard Tobin <ri*****@cogsci.ed.ac.ukwrote:
>
Anonymous functions are almost always going to be *nested* functions,
which opens the whole can of worms concerning non-local variables.
Can these functions refer to, and modify, variables in the containing
function?
Yes they can. The containing function passes its own frame pointer as an
extra hidden argument to the nested function.
What happens if you return the functions to outside the
scope of the containing function?
That's very similar to returning a pointer to an auto variable. The return
doesn't extend the lifetime of the thing being referenced. When you try to
call the nested function through that returned pointer, the GCC manual warns
us: "all hell will break loose".

A pointer to a nested function is actually 2 pointers: a pointer to the code
and a copy of the frame pointer of the corresponding instance of the
containing function. Whenever a pointer to a nested function is required, a
wrapper function is dynamically created to encapsulate those 2 pointers.
Passing this wrapper-pointer down to qsort works fine, but you can't return
it. Not only does it require the use of the containing function's local
variables which are now dead, the wrapper function (trampoline) itself died
along with them.

--
Alan Curry
pa****@world.std.com
Apr 21 '07 #31
In article <f0**********@pcls6.std.com>,
Alan Curry <pa****@TheWorld.comwrote:
>>Anonymous functions are almost always going to be *nested* functions,
which opens the whole can of worms concerning non-local variables.
Can these functions refer to, and modify, variables in the containing
function?
>Yes they can. [...]
Just to be clear, I was not asking specifically about GCC's
implementation, but pointing out questions that had to be addressed
when adding them to a language.

-- Richard
--
"Consideration shall be given to the need for as many as 32 characters
in some alphabets" - X3.4, 1963.
Apr 21 '07 #32
In article <-Y******************************@bt.com>,
Richard Heathfield <rj*@see.sig.invalidwrote:
>Your example evaluates at least one argument twice. The example with
the GNU syntax doesn't.
>That is certainly true, but irrelevant unless the caller is abusing the
preprocessor by using macro arguments which oughtn't to be evaluated
more than once.
I think this confirms what I said in another article. That you
consider this to be an abuse of the preprocessor is just a consequence
of the language as it is; macro arguments in many other languages are
not expected to be limited in this way.

-- Richard
--
"Consideration shall be given to the need for as many as 32 characters
in some alphabets" - X3.4, 1963.
Apr 21 '07 #33
"jacob.navia" <ja***@jacob.remcomp.frwrites:
[...]
As you may know, macros and function calls are not
easy to distinguish in C.

You HAVE TO KNOW that you are calling a macro and not a function.
You may know that, or you may not.
The convention is to use all-caps names for macros.
What is important for language coherence and transparency is that

foo(i++);

evaluates i only once if it is a macro or not.
No matter how many features you add to the language to make it
possible for foo(i++) to evaluate its argument only once, it will
still be possible to define a macro foo() that evaluates its argument
multiple times (unless you break existing code). If you write a call
to foo(), and foo() might be a macro, you *still* have to determine
how it evaluates its arguments. Or you can play it safe and do this:

foo(i);
i++;

(and if foo() does evaluate its argument more than once, complain
bitterly to the author for not calling it FOO()).

--
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"
Apr 21 '07 #34
In article <ln************@nuthaus.mib.org>,
Keith Thompson <ks***@mib.orgwrote:
>No matter how many features you add to the language to make it
possible for foo(i++) to evaluate its argument only once, it will
still be possible to define a macro foo() that evaluates its argument
multiple times (unless you break existing code). If you write a call
to foo(), and foo() might be a macro, you *still* have to determine
how it evaluates its arguments.
True, but determining this might merely amount to reading a statement
"all the macros in this library evaluate their arguments exactly
once", which is a guarantee that is currently hard to give.

-- Richard

--
"Consideration shall be given to the need for as many as 32 characters
in some alphabets" - X3.4, 1963.
Apr 21 '07 #35
In article <ln************@nuthaus.mib.org>,
Keith Thompson <ks***@mib.orgwrote:
>"jacob.navia" <ja***@jacob.remcomp.frwrites:
[Anonymous functions]
>How would they look like in C?

No idea.
Like C99's compound literals? A block statement constituting the body
of the function, cast to a function pointer type.
The cast would have to name the function arguments, to identify them in
the body.

So they'd be used something like:
--------
qsort(arr,num,sizeof *arr,
(int (*)(const void *va,const void *vb)){
int *a=va;int *b=vb; return (*a<*b)?(-1):(*a>*b);});
--------
dave
(or we could figure out some way to make "lambda" work as a keyword)

--
Dave Vandervies dj******@csclub.uwaterloo.ca
Having met him on several occasions, I can assure you that Bill is not
schizophrenic.
And neither is Bill. --Richard Heathfield in comp.lang.c
Apr 21 '07 #36
Ian Collins <ia******@hotmail.comwrites:
[...]
Maybe they were introduced before inline functions? The only use I
could see where inline functions don't apply was as a form of generics
inside a macro. But as you say, the need for this can be avoided by not
abusing the preprocessor.
The only form of control flow available in a function-like macro is
usually the ternary operator (and && and ||). gcc-like compound
statement expressions let you use, for example, if, while, and for
statements.

--
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"
Apr 21 '07 #37
Keith Thompson wrote:
Ian Collins <ia******@hotmail.comwrites:
[...]
>>Maybe they were introduced before inline functions? The only use I
could see where inline functions don't apply was as a form of generics
inside a macro. But as you say, the need for this can be avoided by not
abusing the preprocessor.


The only form of control flow available in a function-like macro is
usually the ternary operator (and && and ||). gcc-like compound
statement expressions let you use, for example, if, while, and for
statements.
Eh?

#define fluf( array, size, n ) \
{ size_t index = 0; n = 0; \
while( index < size ) { n += array[index++]; } }

--
Ian Collins.
Apr 21 '07 #38
On Sat, Apr 21, 2007 at 06:21:16PM +0000, Richard Heathfield wrote:
Michal Nazarewicz said:

<snip>
Certainly it wouldn't make sens to introduce anonymous functions just
to allow abusing preprocessor as we have inline functions in C99.

Agreed.
IMO there's not much use for them anyway. The only thing I can think
of is:

qsort(array, sizeof array / sizeof *array, sizeof *array,
({ some kind of strange syntax }));

Interesting. Perhaps something like this:

{ :formal parameter list: { body goes here } value; }
and it's not like one uses callback functions every 10th line of code.

Yeah, this does look like a solution looking for a problem.
Please excuse my butting in here given my relative lack of experience and
expertise, but it seems that there is a point that everyone here is missing
about this problem. If it is usually considered necessary and good to
prevent side-effects from occuring when variables are expanded in macros,
then why is it that the pre-processor is not defined to ensure this doesn't
occur?
Regards,

Steve

Apr 21 '07 #39
In article <58*************@mid.individual.net>,
Ian Collins <ia******@hotmail.comwrote:
>The only form of control flow available in a function-like macro is
usually the ternary operator (and && and ||). gcc-like compound
statement expressions let you use, for example, if, while, and for
statements.
>Eh?

#define fluf( array, size, n ) \
{ size_t index = 0; n = 0; \
while( index < size ) { n += array[index++]; } }
This is not function-like in that it cannot return a value. The GCC
extension lets you return a value from a block.

-- Richard

--
"Consideration shall be given to the need for as many as 32 characters
in some alphabets" - X3.4, 1963.
Apr 21 '07 #40
Steve Thompson said:

<snip>
If it is usually considered necessary and good to
prevent side-effects from occuring when variables are expanded in
macros, then why is it that the pre-processor is not defined to ensure
this doesn't occur?
Side effects aren't necessarily the problem. Indeed, adding a side
effect may on occasion be the whole point of defining a macro.

The problem comes when a macro argument is evaluated twice or more and
is written in such a way that this re-evaluation is significant in a
bad way. This happens surprisingly rarely - it seems to be one of the
few C pitfalls that students do actually learn about during their
formal studies, and it is easy enough to remember not to do it - so it
isn't really all that big a deal after all.

--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999
http://www.cpax.org.uk
email: rjh at the above domain, - www.
Apr 21 '07 #41
>Keith Thompson wrote:
>The only form of control flow available in a function-like macro ...
In article <58*************@mid.individual.net>
Ian Collins <ia******@hotmail.comwrote:
>Eh?

#define fluf( array, size, n ) \
{ size_t index = 0; n = 0; \
while( index < size ) { n += array[index++]; } }
Here, "fluf" *is* a macro, but is not a *function-like* macro:

x = fluf(a, b, c);

produces a syntax error.
>[but] gcc-like compound statement expressions let you use, for
example, if, while, and for statements.
I still prefer inline functions, which have "more obvious" semantics
than gcc's ({ ... }) statement-expressions (and are even in C99 :-) ).
The function versions avoid name clashes in the usual way that
functions avoid name clashes: we know that at "function call" time
the actual arguments are bound to the formal parameter variables,
and use of the inline function's local variables works in the usual
manner.

Although it is off topic here, I will, however, note that we found
that gcc's inline assembly behaved differently (in at least some
versions of gcc) if put into an inline function. In particular,
while:

static inline int magic_instruction(args) {
...
__asm__ __volatile__("some instruction" : "outputs" : "inputs");
...
return whatever;
}

and:

#define magic_instruction(args) ({ \
... \
__asm__ __volatile__("some instruction" : "outputs" : "inputs"); \
... \
whatever; \
})

both "worked" (modulo compiler bugs and getting the constraints
right on the input and output strings given to the __asm__), the
expression version ({...}) generated better code on the x86 than
the inline function version. (Exactly why was not clear -- both
compilations had the same optimization flags -- and I never
investigated further. I simply gave up on trying to convince people
to use the inline function version. Both were irrevocably intertwined
with using gcc anyway; if we were to use another compiler, either
method could be usually replaced with a call to assembly code in
a separate file, without changing the rest of the C code.)
--
In-Real-Life: Chris Torek, Wind River Systems
Salt Lake City, UT, USA (40°39.22'N, 111°50.29'W) +1 801 277 2603
email: forget about it http://web.torek.net/torek/index.html
Reading email is like searching for food in the garbage, thanks to spammers.
Apr 21 '07 #42
Richard Tobin wrote:
In article <58*************@mid.individual.net>,
Ian Collins <ia******@hotmail.comwrote:

>>>The only form of control flow available in a function-like macro is
usually the ternary operator (and && and ||). gcc-like compound
statement expressions let you use, for example, if, while, and for
statements.

>>Eh?

#define fluf( array, size, n ) \
{ size_t index = 0; n = 0; \
while( index < size ) { n += array[index++]; } }


This is not function-like in that it cannot return a value. The GCC
extension lets you return a value from a block.
OK, but it is void function-like!

--
Ian Collins.
Apr 22 '07 #43
Chris Torek <no****@torek.netwrites:
>>Keith Thompson wrote:
>>The only form of control flow available in a function-like macro ...
In article <58*************@mid.individual.net>
Ian Collins <ia******@hotmail.comwrote:
>>Eh?

#define fluf( array, size, n ) \
{ size_t index = 0; n = 0; \
while( index < size ) { n += array[index++]; } }

Here, "fluf" *is* a macro, but is not a *function-like* macro:

x = fluf(a, b, c);

produces a syntax error.
[...]

Strictly speaking, it is a function-like macro (and I should have been
clearer on that point upthread). An object-like macro is one that
takes no arguments; a function-like macro is one that takes arguments
(the standard defines both terms). But not all function-like macros
can actually be used as if they were functions.

My point was that a macro that can actually be used like a function
can't use if, while, and for statements; gcc's compound statement
expressions make this possible. (I'm not necessarily arguing that
they should be added to the standard, though suppose I I wouldn't
mind.)
[...]

--
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"
Apr 22 '07 #44
jacob navia wrote:
Gnu C features some interesting extensions, among others
compound statements that return a value. For instance:

({ int y = foo(); int z;
if (y>0) z = y; else z=-y;
z;
})
A block enclosed by braces can appear within parentheses
to form a block that "returns" a value. This is handy
in some macros, or in other applications.

Actually this construct is nothing more (and nothing less)
than anonymous functions.
It's no more an anonymous function than a five-pound note
is a Brandenburg concerto.

The point about an anonymous function is that it's a /function/,
something you can apply to arguments, and -- in most modern
and decent languages -- that you can treat as a first-class
value, ie, pass it as an argument, return it as a result,
store it in a variable, that sort of thing [1]. The GCC
feature above doesn't do that (it /is/ anonymous, though).

It's a poor man's VALOF-RESULTIS.

[1] That C calls those things "function /pointers/" doesn't
materially affect the argument.

--
BCPL & Pop11 Hedgehog
The shortcuts are all full of people using them.

Apr 22 '07 #45
Steve Thompson wrote:
On Sat, Apr 21, 2007 at 06:21:16PM +0000, Richard Heathfield wrote:
>Michal Nazarewicz said:

<snip>
>>Certainly it wouldn't make sens to introduce anonymous functions just
to allow abusing preprocessor as we have inline functions in C99.
Agreed.
>>IMO there's not much use for them anyway. The only thing I can think
of is:

qsort(array, sizeof array / sizeof *array, sizeof *array,
({ some kind of strange syntax }));
Interesting. Perhaps something like this:

{ :formal parameter list: { body goes here } value; }
>>and it's not like one uses callback functions every 10th line of code.
Yeah, this does look like a solution looking for a problem.

Please excuse my butting in here given my relative lack of experience and
expertise, but it seems that there is a point that everyone here is missing
about this problem. If it is usually considered necessary and good to
prevent side-effects from occuring when variables are expanded in macros,
then why is it that the pre-processor is not defined to ensure this doesn't
occur?
Regards,

Steve
Apr 22 '07 #46

(Sorry for earlier blank reply; hit Send too soon.)

Steve Thompson wrote:
>
Please excuse my butting in here given my relative lack of experience and
expertise, but it seems that there is a point that everyone here is missing
about this problem. If it is usually considered necessary and good to
prevent side-effects from occuring when variables are expanded in macros,
then why is it that the pre-processor is not defined to ensure this doesn't
occur?
Because "the preprocessor doesn't know C." That is, the
preprocessor just deals with a sequence of tokens (formally,
"preprocessing tokens") but doesn't attach any meaning to
them unless they happen to be macro identifiers or preprocessor
directives. The preprocessor doesn't know that `int' is a
numeric type, that `extern' is a storage class specifier, or
that `++' is an operator. And in particular, the preprocessor
cannot tell which sequences of tokens have side-effects and
which do not.

--
Eric Sosman
es*****@acm-dot-org.invalid
Apr 22 '07 #47
jacob.navia wrote:
>
As you may know, macros and function calls are not
easy to distinguish in C.
This is just a special case of "macros and any construct
whatsoever are not easy to distinguish in C." If you come
across

x = MACRO(y, z);

you may suspect that MACRO is a macro identifier, and you may
even guess that it is a function-like macro (although that's
by no means certain), but you still don't know its expansion.

#define MACRO(u,v) sqrt((u) * (v))
#define MACRO(p,q) p ## q
#define MACRO ++n ,
You HAVE TO KNOW that you are calling a macro and not a function.
You may know that, or you may not.
In C as it stands this has to be a matter of documentation.
You have to know that MACRO is a macro (and what it's good for)
in the same way that you have to know that fflush(stdin) is no
good.

"C as it stands" means, more or less, "C with a preprocessor."
As long as the preprocessor is powerful enough to generate any
arbitrary sequence of source tokens, and as long as it operates
"before" those parts of C that attach meanings to the tokens, the
job of understanding what a macro does must remain a matter for
documentation. One can imagine a C-ish language in which macro
invocations were set off by a special syntax, e.g.

if ((ch = getchar()) == #EOF) ...
#assert(x <= #INT_MAX / 2);

.... but I don't think this would be an improvement. Yes, it
would make the reader of source code aware that a macro was in
use, but it still wouldn't solve the rest of the documentation
issue -- and if you need to look up the documentation for #MACRO
anyhow, you might as well look up the documentation for MACRO.
Meanwhile, it would give up the ability to do things like

#undef malloc
#define malloc debug_malloc
What is important for language coherence and transparency is that

foo(i++);

evaluates i only once if it is a macro or not.
Horse non-proximal to barn, I'm afraid. A "pre"processor
more fully integrated with the rest of the language would be a
Good Thing in some ways (e.g., ability to #if a typedef), but
the language would not be a lot like C. If you want PL/I (and
its more closely integrated source-transformer), you know where
to find it.

--
Eric Sosman
es*****@acm-dot-org.invalid
Apr 22 '07 #48
On Sat, Apr 21, 2007 at 11:43:55PM +0000, Richard Heathfield wrote:
Steve Thompson said:

<snip>
If it is usually considered necessary and good to
prevent side-effects from occuring when variables are expanded in
macros, then why is it that the pre-processor is not defined to ensure
this doesn't occur?

Side effects aren't necessarily the problem. Indeed, adding a side
effect may on occasion be the whole point of defining a macro.
Well, yes. C macros are often useful precisely because they have that
property, but those sorts of macros are rare. I think most people do not
really want to expose their programs to the risks associated with the use
of byzantine macro constructs.
The problem comes when a macro argument is evaluated twice or more and
is written in such a way that this re-evaluation is significant in a
bad way. This happens surprisingly rarely - it seems to be one of the
few C pitfalls that students do actually learn about during their
formal studies, and it is easy enough to remember not to do it - so it
isn't really all that big a deal after all.
I was just wondering why it is that the C pre-processor was not defined to
fix this problem. It is not a stretch to imagine that macro definitions
such as

#define foo(x, y) ({ if (y >0) (x / y); else x; })

could be automatically treated by the preprocessor as if it were something
like

#define foo(x, y) ({ typeof(x) __x = x; typeof(y) __y; \
if(__y 0) (__x /__y); else (__x); })

I suppose you could say that if you need that behaviour, then you should
write an inline function, but that fails to address the usability risk
involved in macros that evaluate their parameters more than once. IMHO it
is a needless risk.
Regards,

Steve

Apr 22 '07 #49
On Sun, Apr 22, 2007 at 08:24:40AM -0400, Eric Sosman wrote:
>
(Sorry for earlier blank reply; hit Send too soon.)

Steve Thompson wrote:

Please excuse my butting in here given my relative lack of experience and
expertise, but it seems that there is a point that everyone here is missing
about this problem. If it is usually considered necessary and good to
prevent side-effects from occuring when variables are expanded in macros,
then why is it that the pre-processor is not defined to ensure this doesn't
occur?

Because "the preprocessor doesn't know C." That is, the
preprocessor just deals with a sequence of tokens (formally,
"preprocessing tokens") but doesn't attach any meaning to
them unless they happen to be macro identifiers or preprocessor
directives. The preprocessor doesn't know that `int' is a
numeric type, that `extern' is a storage class specifier, or
that `++' is an operator. And in particular, the preprocessor
cannot tell which sequences of tokens have side-effects and
which do not.
Aha; that was what I was trying to get at. But as you imply the
preprocessor knows a little bit about C, specifically it almost knows what
a function argument is. In my reply to Mr. Heathfield I ask whether the
pre-processor could not automatically protect macro arguments at very
little cost to the language.
Regards,

Steve

Apr 22 '07 #50

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

Similar topics

0
2053
by: Carlos Ribeiro | last post by:
I thought about this problem over the weekend, after long hours of hacking some metaclasses to allow me to express some real case data structures as Python classes. I think that this is something...
76
3686
by: Nick Coghlan | last post by:
GvR has commented that he want to get rid of the lambda keyword for Python 3.0. Getting rid of lambda seems like a worthy goal, but I'd prefer to see it dropped in favour of a different syntax,...
6
3435
by: Mark Brandyberry | last post by:
I have a bit of a problem with an overloaded operator that I'm writing that I have distilled down to an example in the code below. Essentially, I have an operator function (+=) that takes a...
6
6972
by: Gaijinco | last post by:
I have always felt that there are a lot of topics that you learned the facts but you only grasp the matter sometime down the road. For me, two of those topics are inner classes and anonymous...
7
2842
by: Gregor Kofler | last post by:
What is the best practice for removing anonymous functions? Something like (function() { doSomething(); arguments.callee = null; })(); seems to work (at least it triggers no errors or...
22
3883
by: Luna Moon | last post by:
I am reading the book "C++ Annotations", and here is a quote from the book: Namespaces can be defined without a name. Such a namespace is anonymous and it restricts the visibility of the...
0
7353
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
7418
jinu1996
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...
0
7508
tracyyun
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...
1
5063
isladogs
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...
0
4737
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and...
0
3212
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
0
1572
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 ...
1
781
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.
0
446
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence...

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.