Compound statements in expressions

F

Fredrik Tolf

Take a look at this C snippet:

#include <stdio.h>

int test(int *var)
{
return(*var += 5);
}

int main(void)
{
int var;

var = 1;
printf("%i %i %i\n", ({var += 4; var;}),
(printf("%i\n", test(&var)), var),
(var += 10, var -= 4));
}

When compiled with GCC 3.3, it outputs the following when run:
6
10 16 16

Now I'm wondering - Are these types of constructs allowed by the C
standard, or are they GCC extensions? If they are standardized, what is
the standardized semantics. That is, in which order are they intended to
be executed, what's the difference between "(var += 4, var)" and "({var
+=4; var;})", and what does "(expr1, expr2, expr3)" really mean when
it's not an argument list to a function.

Also, why must I write "({var += 4; var;})" - Why can't I skip the outer
parentheses?

Thanks for your attention!

Fredrik Tolf
 
K

Keith Thompson

Fredrik Tolf said:
Take a look at this C snippet:

#include <stdio.h>

int test(int *var)
{
return(*var += 5);
}

int main(void)
{
int var;

var = 1;
printf("%i %i %i\n", ({var += 4; var;}),
(printf("%i\n", test(&var)), var),
(var += 10, var -= 4));
}

When compiled with GCC 3.3, it outputs the following when run:
6
10 16 16

Now I'm wondering - Are these types of constructs allowed by the C
standard, or are they GCC extensions?

It's a gcc extension.

<OT>
If your system supports it, try
info gcc 'c extensions' 'statement exprs'
</OT>
 
D

Dag Viken

Fredrik Tolf said:
Take a look at this C snippet:

#include <stdio.h>

int test(int *var)
{
return(*var += 5);
}

int main(void)
{
int var;

var = 1;
printf("%i %i %i\n", ({var += 4; var;}),
(printf("%i\n", test(&var)), var),
(var += 10, var -= 4));
}

When compiled with GCC 3.3, it outputs the following when run:
6
10 16 16

Now I'm wondering - Are these types of constructs allowed by the C
standard, or are they GCC extensions? If they are standardized, what is
the standardized semantics. That is, in which order are they intended to
be executed, what's the difference between "(var += 4, var)" and "({var
+=4; var;})", and what does "(expr1, expr2, expr3)" really mean when
it's not an argument list to a function.

Also, why must I write "({var += 4; var;})" - Why can't I skip the outer
parentheses?

Thanks for your attention!

Fredrik Tolf

This does not compile on my system - i.e. VC7 with {} inside ().
I do not think it is valid code.

Dag
 
J

Joona I Palaste

This does not compile on my system - i.e. VC7 with {} inside ().
I do not think it is valid code.

As has already been said, it's a GCC extension. So it's non-standard
code and thus not guaranteed to be valid on *any* specific compiler.
 
D

Dag Viken

Joona I Palaste said:
As has already been said, it's a GCC extension. So it's non-standard
code and thus not guaranteed to be valid on *any* specific compiler.

Why make extensions that are incompatible with the existing C/C++ standards?
It certainly does not encourage source code compatibility. And especially if
it is gcc - is there an upcoming standard that supports these extended
features?
 
J

Joona I Palaste

Why make extensions that are incompatible with the existing C/C++ standards?
It certainly does not encourage source code compatibility. And especially if
it is gcc - is there an upcoming standard that supports these extended
features?

That's what I've been wondering too. Maybe you can ask at gnu.gcc.help
or something?
 
R

Richard Bos

Dag Viken said:
Why make extensions that are incompatible with the existing C/C++ standards?
It certainly does not encourage source code compatibility. And especially if
it is gcc - is there an upcoming standard that supports these extended
features?

You assume that GNU _wants_ source code compatibility. IYAM, they are
second only to M$ for embrace-and-extend, and one cannot help but
suspect that this is quite intentional.

Richard
 
C

CBFalconer

Richard said:
You assume that GNU _wants_ source code compatibility. IYAM,
they are second only to M$ for embrace-and-extend, and one
cannot help but suspect that this is quite intentional.

It is your own fault for not using it with the -ansi -pedantic
switches. Unlike M$ gcc allows all those extensions to be
switched off. I consider it would be preferable to allow them to
be switched on. Then you can think of gcc as a test bed for
possible new features.
 
D

Dan Pop

Joona I Palaste said:
Dag Viken said:
news:[email protected]... [snip]

Now I'm wondering - Are these types of constructs allowed by the C
standard, or are they GCC extensions?

You can trivially get the answer yourself, by compiling with gcc in
standard conforming mode (the -ansi -pedantic options). If you get a
clean compile, they are probably allowed by the C standard (the other
possibility is that they invoke undefined behaviour, so no diagnostic is
require).
Why make extensions that are incompatible with the existing C/C++ standards?

Why not, as long as they don't break *any* correct C program?
It certainly does not encourage source code compatibility.

If the extension is useful, it becomes existing practice for a future
revision of the C standard. That is, assuming that the standardisation
committee is looking for existing practice in the right places...

Most of the gcc extensions are far from gratuitous and it is a pity that
the C standardisation process has ignored/rejected them. The one you're
talking about greatly improves the functionality of function-like macros,
especially when used together with another gcc extension: typeof.
And especially if
it is gcc - is there an upcoming standard that supports these extended
features?

For the time being, there is no upcoming C standard. Merely bug fixes to
the current standard.

Dan
 
F

Fredrik Tolf

It's a gcc extension.

<OT>
If your system supports it, try
info gcc 'c extensions' 'statement exprs'
</OT>

I see. I guess I should have tried -ansi, but I didn't think of it.
However, that texinfo only mentions these ({...}) constructs. How about
this:

printf("%i\n", (var += 10, var -= 4));

GCC accepts that with -Wall -pedantic -ansi, so I guess that is standard
C. But again, what does it really mean?

Fredrik Tolf
 
C

Chris Dollin

Fredrik said:
I see. I guess I should have tried -ansi, but I didn't think of it.
However, that texinfo only mentions these ({...}) constructs. How about
this:

printf("%i\n", (var += 10, var -= 4));

GCC accepts that with -Wall -pedantic -ansi, so I guess that is standard
C. But again, what does it really mean?

It's a straightforward (but stupid) use of the comma operator.

E1, E2 [where the comma is *not* an argument separator]

means "evaluate E1, throw away the result, evaluate E2 and return its
result as the result of the entire expression".
 
F

Fredrik Tolf

Fredrik said:
I see. I guess I should have tried -ansi, but I didn't think of it.
However, that texinfo only mentions these ({...}) constructs. How about
this:

printf("%i\n", (var += 10, var -= 4));

GCC accepts that with -Wall -pedantic -ansi, so I guess that is standard
C. But again, what does it really mean?

It's a straightforward (but stupid) use of the comma operator.

E1, E2 [where the comma is *not* an argument separator]

means "evaluate E1, throw away the result, evaluate E2 and return its
result as the result of the entire expression".

I see. Am I correct if I say that declarations cannot be part of comma-
separated statements?

Fredrik Tolf
 
C

Chris Dollin

Fredrik said:
Fredrik said:
I see. I guess I should have tried -ansi, but I didn't think of it.
However, that texinfo only mentions these ({...}) constructs. How about
this:

printf("%i\n", (var += 10, var -= 4));

GCC accepts that with -Wall -pedantic -ansi, so I guess that is
standard C. But again, what does it really mean?

It's a straightforward (but stupid) use of the comma operator.

E1, E2 [where the comma is *not* an argument separator]

means "evaluate E1, throw away the result, evaluate E2 and return its
result as the result of the entire expression".

I see. Am I correct if I say that declarations cannot be part of comma-
separated statements?

Yes, but only because there aren't any comma-separated statements.
The comma-expression's operands are expressions, not statements.

[Assignments are, technically, expressions, although of course they're
very statement-like things, since they're primarily executed for effect
not value. But I'm picking the syntactic definition for statements
here, since the semantic one isn't so useful.]
 
D

Dan Pop

In said:
I see. I guess I should have tried -ansi, but I didn't think of it.
However, that texinfo only mentions these ({...}) constructs. How about
this:

printf("%i\n", (var += 10, var -= 4));

GCC accepts that with -Wall -pedantic -ansi, so I guess that is standard
C. But again, what does it really mean?

Ever considered reading a C book?

Dan
 
E

Eric Sosman

Fredrik said:
Fredrik Tolf wrote:

I see. I guess I should have tried -ansi, but I didn't think of it.
However, that texinfo only mentions these ({...}) constructs. How about
this:

printf("%i\n", (var += 10, var -= 4));

GCC accepts that with -Wall -pedantic -ansi, so I guess that is standard
C. But again, what does it really mean?

It's a straightforward (but stupid) use of the comma operator.

E1, E2 [where the comma is *not* an argument separator]

means "evaluate E1, throw away the result, evaluate E2 and return its
result as the result of the entire expression".


I see. Am I correct if I say that declarations cannot be part of comma-
separated statements?

There are no "comma-separated statements" in C. The
examples above are *expressions* using the comma *operator*,
whose two operands are themselves sub-expressions. Would
you call `a / b' a "slash-separated statement?" This may
seem like pointless pedantry at first sight, and maybe even
at second or third sight. However, it contains the answer to
your immediate question, and perhaps to many other questions
that might occur to you later.

Rephrased, the question becomes "Can declarations appear
in expressions?" For the current C Standard, the answer is
"No," unequivocally. For the now-obsolete former Standard,
the answer is "Only in one special case," namely, that the
invocation of a previously undeclared function serves as a
declaration of that function. If f() and g() have not been
declared,

a + f()
b , g()

are expressions that are erroneous under the current Standard,
but that implicitly declare f() and g() as functions returning
`int' values under the obsolete Standard. No other kinds of
declarations can appear in expressions, under either Standard.
 
F

Fredrik Tolf

Fredrik said:
Fredrik Tolf wrote:

I see. I guess I should have tried -ansi, but I didn't think of it.
However, that texinfo only mentions these ({...}) constructs. How about
this:

printf("%i\n", (var += 10, var -= 4));

GCC accepts that with -Wall -pedantic -ansi, so I guess that is
standard C. But again, what does it really mean?

It's a straightforward (but stupid) use of the comma operator.

E1, E2 [where the comma is *not* an argument separator]

means "evaluate E1, throw away the result, evaluate E2 and return its
result as the result of the entire expression".

I see. Am I correct if I say that declarations cannot be part of comma-
separated statements?

Yes, but only because there aren't any comma-separated statements.
The comma-expression's operands are expressions, not statements.

Oh, that makes it make sense. Actually, I should have seen that, but oh
well...

Thanks for your time!

Fredrik Tolf
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,484
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top