Hello, C++.
I'm having some difficulty (amending Emacs's C++ Mode) reconciling the
two conflicting uses in C++ of ({.
Firstly, it is used as a "statement expression", a GCC enhancement also
found in C, allowing a more relaxed and natural way to write an
expression as the end result of a sequence of statements:
({ int y = foo (); int z;
if (y > 0) z = y;
else z = - y;
z; })
. I think this usage is very old.
Secondly, there's initialisation expressions like:
void f4 (int a, int b, int c)
{
std::vector<ABC> abcList2(
{{a+6,
b+6,
c+6}
}
);
....
}
. Here the ( on the std::vector line, together with the next {, can be confused as a statement expression, though it's clearly not meant that
way. I think this syntax is much newer than the other one, though I may
be wrong here.
In calculating the indentation for source lines in these constructs, the ambiguity causes mis-indentation for one or the other of them.
Now to my question: how common is GCC's statement expression in the wide world of C++ source code? How much would be lost if I simply removed the statement expression from C++ Mode's parsing functions?
Hello, C++.
I'm having some difficulty (amending Emacs's C++ Mode) reconciling the
two conflicting uses in C++ of ({.
Firstly, it is used as a "statement expression", a GCC enhancement also
found in C, allowing a more relaxed and natural way to write an
expression as the end result of a sequence of statements:
({ int y = foo (); int z;
if (y > 0) z = y;
else z = - y;
z; })
. I think this usage is very old.
Secondly, there's initialisation expressions like:
void f4 (int a, int b, int c)
{
std::vector<ABC> abcList2(
{{a+6,
b+6,
c+6}
}
);
....
}
. Here the ( on the std::vector line, together with the next {, can be confused as a statement expression, though it's clearly not meant that
way. I think this syntax is much newer than the other one, though I may
be wrong here.
In calculating the indentation for source lines in these constructs, the ambiguity causes mis-indentation for one or the other of them.
Now to my question: how common is GCC's statement expression in the wide world of C++ source code? How much would be lost if I simply removed the statement expression from C++ Mode's parsing functions?
It appears the statement expressions are a gcc extension which does[...]
not even compile in standard C++, and is probably not needed for
anything in C++ as there are better options like templated and inlined functions.
In C there might be some usage case for it.
Statement expressions don't compile in *standard* C or C++.
On 20.03.2025 20:27, Alan Mackenzie wrote:
Hello, C++.
I'm having some difficulty (amending Emacs's C++ Mode) reconciling the
two conflicting uses in C++ of ({.
Firstly, it is used as a "statement expression", a GCC enhancement also
found in C, allowing a more relaxed and natural way to write an
expression as the end result of a sequence of statements:
({ int y = foo (); int z;
if (y > 0) z = y;
else z = - y;
z; })
. I think this usage is very old.
Secondly, there's initialisation expressions like:
void f4 (int a, int b, int c)
{
std::vector<ABC> abcList2(
{{a+6,
b+6,
c+6}
}
);
....
}
. Here the ( on the std::vector line, together with the next {, can be
confused as a statement expression, though it's clearly not meant that
way. I think this syntax is much newer than the other one, though I may
be wrong here.
This braced initialization (called "List-initialization") was introduced
in C++11, it is standardized and in wide and growing use.
In calculating the indentation for source lines in these constructs, the
ambiguity causes mis-indentation for one or the other of them.
Now to my question: how common is GCC's statement expression in the wide
world of C++ source code? How much would be lost if I simply removed the
statement expression from C++ Mode's parsing functions?
It appears the statement expressions are a gcc extension which does not
even compile in standard C++, and is probably not needed for anything in
C++ as there are better options like templated and inlined functions.
In C there might be some usage case for it.
During the last 25 years I do not recall having encountered this feature ever, and I do not even recall anyone bashing it. So I guess it could be ditched pretty easily.
Paavo Helde <eesnimi@osa.pri.ee> writes:
[...]
It appears the statement expressions are a gcc extension which does[...]
not even compile in standard C++, and is probably not needed for
anything in C++ as there are better options like templated and inlined
functions.
In C there might be some usage case for it.
Statement expressions don't compile in *standard* C or C++.
gcc supports them as an extension for both C and C++ (and Objective-C).
----
Keith Thompson (The_Other_Keith) Keith.S.Thompson+u@gmail.com
void Void(void) { Void(); } /* The recursive call of the void */
Am 21.03.2025 um 20:27 schrieb Keith Thompson:
Statement expressions don't compile in *standard* C or C++.
In C++ you could use lambdas for that.
Paavo Helde <eesnimi@osa.pri.ee> wrote:
On 20.03.2025 20:27, Alan Mackenzie wrote:
It appears the statement expressions are a gcc extension which does not
even compile in standard C++, and is probably not needed for anything in
C++ as there are better options like templated and inlined functions.
In C there might be some usage case for it.
I'm not sure what you meant by templated functions here, but an inline >function has the disadvantage of fragmenting the code. Rather than have
a few lines of code where they're used, you need to look somewhere else
to see what they do.
({ int y = foo (); int z;
if (y > 0) z = y;
else z = - y;
z; })
If the sign of y is badly predictible you may chose:
z = (y >> sizeof(y) * CHAR_BIT - 1) * y;
Paavo Helde <eesnimi@osa.pri.ee> wrote:
It appears the statement expressions are a gcc extension which does not
even compile in standard C++, and is probably not needed for anything in
C++ as there are better options like templated and inlined functions.
In C there might be some usage case for it.
I'm not sure what you meant by templated functions here, but an inline function has the disadvantage of fragmenting the code. Rather than have
a few lines of code where they're used, you need to look somewhere else
to see what they do.
Alan Mackenzie <acm@muc.de> writes:
Paavo Helde <eesnimi@osa.pri.ee> wrote:
On 20.03.2025 20:27, Alan Mackenzie wrote:
It appears the statement expressions are a gcc extension which does not >>> even compile in standard C++, and is probably not needed for anything in >>> C++ as there are better options like templated and inlined functions.
In C there might be some usage case for it.
I'm not sure what you meant by templated functions here, but an inline >>function has the disadvantage of fragmenting the code. Rather than have
a few lines of code where they're used, you need to look somewhere else
to see what they do.
An inline function name should be chosen such that it is sufficient to
define exactly what the effect of the function call will be, while
still hiding the implementation and improving readability.
Scott Lurndal <scott@slp53.sl.home> wrote:
Alan Mackenzie <acm@muc.de> writes:
Paavo Helde <eesnimi@osa.pri.ee> wrote:
On 20.03.2025 20:27, Alan Mackenzie wrote:
It appears the statement expressions are a gcc extension which does not >>>> even compile in standard C++, and is probably not needed for anything in >>>> C++ as there are better options like templated and inlined functions.
In C there might be some usage case for it.
I'm not sure what you meant by templated functions here, but an inline >>>function has the disadvantage of fragmenting the code. Rather than have >>>a few lines of code where they're used, you need to look somewhere else >>>to see what they do.
An inline function name should be chosen such that it is sufficient to
define exactly what the effect of the function call will be, while
still hiding the implementation and improving readability.
Yes, that's fine in theory. In practice, meaning while debugging, a
whole lot of midget functions, each called something like >convert_next_char_to_upper_case_is_it_Q_p is a nightmare.
On 22.03.2025 12:53, Alan Mackenzie wrote:
Paavo Helde <eesnimi@osa.pri.ee> wrote:
It appears the statement expressions are a gcc extension which does not
even compile in standard C++, and is probably not needed for anything in >>> C++ as there are better options like templated and inlined functions.
In C there might be some usage case for it.
I'm not sure what you meant by templated functions here, but an inline
function has the disadvantage of fragmenting the code. Rather than have
a few lines of code where they're used, you need to look somewhere else
to see what they do.
At the GCC page for statement expressions they say "This feature is especially useful in making macro definitions “safe” (so that they evaluate each operand exactly once)" and most of their examples are
about macros.
A macro is fragmenting the code exactly in the same way as an inline function, except the macros are worse than functions in multiple ways.
In C one might argue macros are needed for supporting multiple types at
the same time, but in C++ this is solved much better by function templates.
Ergo, a C-style macro using statement expressions can easily replaced
with a more regular and better behaving function or function template in C++, with no increase in code "fragmentation".
For "in-place" use Bonita is right a lambda can be used to the same
effect, but the readability probably does not go better. As per the
first example on the GCC page (poor man implementation of abs()):
int a = ({ int y = foo (); int z; if (y > 0) z = y; else z = - y; z; });
On 20.03.2025 20:27, Alan Mackenzie wrote:
Hello, C++.
I'm having some difficulty (amending Emacs's C++ Mode) reconciling the
two conflicting uses in C++ of ({.
Firstly, it is used as a "statement expression", a GCC enhancement also
found in C, allowing a more relaxed and natural way to write an
expression as the end result of a sequence of statements:
({ int y = foo (); int z;
if (y > 0) z = y;
else z = - y;
z; })
. I think this usage is very old.
Secondly, there's initialisation expressions like:
void f4 (int a, int b, int c)
{
std::vector<ABC> abcList2(
{{a+6,
b+6,
c+6}
}
);
....
}
. Here the ( on the std::vector line, together with the next {, can be
confused as a statement expression, though it's clearly not meant that
way. I think this syntax is much newer than the other one, though I may
be wrong here.
This braced initialization (called "List-initialization") was introduced
in C++11, it is standardized and in wide and growing use.
Sysop: | DaiTengu |
---|---|
Location: | Appleton, WI |
Users: | 1,029 |
Nodes: | 10 (1 / 9) |
Uptime: | 182:15:14 |
Calls: | 13,337 |
Calls today: | 4 |
Files: | 186,574 |
D/L today: |
5,448 files (1,505M bytes) |
Messages: | 3,356,610 |