I came across this weird C++ program.
#include <iostream>
using namespace std;
int main()
{
int a = ({int x; cin >> x; x;});
cout << a;
}
Can anyone explain what is going on? What is this construct called?
It assigns user input value to a and prints it out. it is done by using a Statement Expression.
Statement Expressions are a gnu gcc compiler extension and are not supported by the C/C++ standards. Hence, any code which uses statement expression is not standard conforming and non-portable.
The IBM XL C/C++ v7.0 also support Statement Expressions & its documentation explains them aptly:
Statement Expressions:
A compound statement is a sequence of statements enclosed by braces. In GNU C, a compound statement inside parentheses may appear as an expression in what is called a Statement expression.
.--------------.
V |
>>-(--{----statement--;-+--}--)--------------------------------><
The value of a statement expression is the value of the last simple expression to appear in the entire construct. If the last statement is not an expression, then the construct is of type void and has no value.
Always compile your code by selecting a standard in GCC: use one of the options -ansi, -std=c90 or -std=iso9899:1990, -std=c++03, -std=c++0x; to obtain all the diagnostics required by the standard, you should also specify -pedantic (or -pedantic-errors if you want them to be errors rather than warnings).
It's a GCC extension. Compile your code with the -pedantic flag if you want to get rid of stuff like this (and you really do want to).
It creates an inline scope, declares x within it, reads it from the standard input and the whole statement finally evaluates to x, which is assigned to a.
The comma operator works similarly, although it doesn't require a separate scope. For example:
int x;
int a = (cin >> x, x);
would do the same. All the statements connected with commas will be executed sequentially, and the result of the whole expression will be set to the value of the rightmost operand.
I don't believe that this is standard C++. It's probably a compiler-specific extension that allows an inner scope to evaluate to a value.
Related
I have the simplest c++ statement declaring a variable "a":
int a = ({ int b = 10; b; });
As recent gcc and clang says, it's a valid statement which really declares variable a having value 10.
The question is: what is this? I know about various types of expressions. I know about various types of statements. But I can't find in a c++ 14 standard any mentioning that "block statement as an expression returns latest inner evaluated expression" or something like this.
Could somebody please point me exact lines of a standard saying that is code line is fully valid?
The question is: what is this?
This is a GNU extension to ISO standard C, an extension that is available also for C++, but likewise is not part of ISO C++.
Citing the GCC Manual: Chapter 6 - Extensions to the C Language Family:
...
These extensions are available in C and Objective-C. Most of them are also available in C++. ...
Statement Exprs: Putting statements and declarations inside expressions.
Where the latter is explained in detail in GCC Manual: Section 6.1 - Statements and Declarations in Expressions:
A compound statement enclosed in parentheses may appear as an expression in GNU C. This allows you to use loops, switches, and local variables within an expression.
Recall that a compound statement is a sequence of statements surrounded by braces; in this construct, parentheses go around the braces. For example:
({ int y = foo (); int z;
if (y > 0) z = y;
else z = - y;
z; })
is a valid (though slightly more complex than necessary) expression for the absolute value of foo ().
...
As for Clang, the Clang Language Extensions describes that Clang aims to support many GCC extensions: [emhpasis mine]:
This document describes the language extensions provided by Clang. In addition to the language extensions listed here, Clang aims to support a broad range of GCC extensions. Please see the GCC manual for more information on these extensions.
I have below discovery by chance. The compiler compiles the below code without any error or warning. Please help me understand why the compiler is not throwing any error? The program contains just a string in a double quotation.
I have not declared any char array neither assigned the below string to any variable.
void main()
{
"Why there is no error in compilation?";
}
Because any expression is a valid statement.
"Why is there no error in compilation?";
is a statement that consists of an expression that evaluates to the given literal string. This is a perfectly valid statement that happens to have no effect whatsoever.
Of course, "useful" statements look more like
a = b;
But well;
b;
is also a valid statement. In your case, b is simply string literal; and you are free to place that within a the body of a method. Obviously this statement doesn't have any side effects; but what if the statement would be something like
"some string " + someFunctionReturningString();
You probably would want that expression to be executed; and as side effect, that method to be called, wouldn't you?
Compile the program with -Wunused-value flag. It just raises
warning: statement with no effect
"Why there is no error in compilation?";
^
That is it.
And If you compile the above code with -Wall flag it also says
warning: return type of ‘main’ is not ‘int’ [-Wmain]
void main() {
void main()
{
"Why there is no error in compilation?";
}
First, let's address the string literal. An expression statement, which is valid in any context where any statement is valid, consists of an (optional) expression followed by a semicolon. The expression is evaluated and any result is discarded. (The empty statement, consisting of just a semicolon, is classified as an expression statement; I'm not sure why.)
Expression statements are very common, but usually used when the expression has side effects. For example, both assignments (x = 42;) and function calls (printf("Hello, world\n")) are expressions, and the both yield values. If you don't care about the result, just add a semicolon and you have a valid statement.
Not all expressions have side effects. Adding a semicolon to an expression that doesn't have any side effects, as you've done here (a string literal is an expression), is not generally useful, but the language doesn't forbid it. Generally C lets you do what you want and lets you worry about whether it makes sense, rather than imposing special-case rules that might prevent mistakes but could also prevent you from doing something useful.
Now let's cover void main(). A lot of people will tell you, with some justification, that this is wrong, and that the correct definition is int main(void). That's almost correct, and it's excellent advice, but the details are more complicated than that.
For a hosted implementation (basically one that provides the standard library), main may be defined in one of three ways:
int main(void) { /* ... */ }
or
int main(int argc, char *argv[]) { /* ... */ }
or equivalent, "or in some other implementation-defined manner." (See N1570 section 5.1.2.2.2 for the gory details.) That means that a particular implementation is permitted to document and implement forms of main other than the two mandated forms. In particular, a compiler can (and some do) state in its documentation that
void main() { /* ... */ }
and/or
void main(void) { /* ... */ }
is valid for that compiler. And a compiler that doesn't explicitly support void main() isn't required to complain if you write void main() anyway. It's not a syntax error or a constraint violation; it just has undefined behavior.
For a freestanding implementation (basically one that targets embedded systems with no OS, and no requirement to support most of the standard library), the entry point is entirely implementation-defined; it needn't even be called main. Requiring void main() is not uncommon for such implementations. (You're probably using a hosted implementation.)
Having said all that, if you're using a hosted implementation, you should always define main with an int return type (and in C you should int main(void) rather than int main()). There is no good reason to use void main(). It makes your program non-portable, and it causes annoying pedants like me to bore you with lengthy discussions of how main should be defined.
A number of C books advise you to use void main(). If you see this, remember who wrote the book and avoid anything written by that author; he or she doesn't know C very well, and will likely make other mistakes. (I'm thinking of Herbert Schildt in particular.) The great irony here is that void keyword was introduced by the 1989 ANSI C standard -- the very same standard that introduced the requirement for main to return int (unless the implementation explicitly permits something else).
I've discussed the C rules so far. Your question is tagged both C and C++, and the rules are a bit different in C++. In C++, empty parentheses on a function declaration or definition have a different meaning, and you should write int main() rather than int main(void) (the latter is supported in C++, but only for compatibility with C). And C++ requires main to return int for hosted implementations, with no permission for an implementation to support void main().
to describe the problem simply, please have a look at the code below:
int main()
{
int a=123;
({if (a) a=0;});
return 0;
}
I got this warning from [-Wsequence-point]
Line 4: warning: operation on 'a' may be undefined
my g++ version is 4.4.5
I'll appreciate whoever would explain this simple problem.
btw you could find my original program and original problem in #7 in this Chinese site (not necessary)
UPD1:
though to change the code into ({if(a) a=0; a;}) can avoid the warning, but I recognized that the real reason of the problem may not be The last thing in the compound statement should be an expression followed by a semicolon.
because the documentary also said If you use some other kind of statement last within the braces, the construct has type void, and thus effectively no value.
an example can show it:
int main()
{
int a=123, b;
({;});
({if (a) b=0;});
return 0;
}
and this code got no warnings!
so I think the real reason is something about sequence point.
please help!
UPD2:
sorry to #AndyProwl for having unaccept his answer which was accepted before UPD1. following his advise I may ask a new question (UPD1 is a new question different from the original one). I'll accept his answer again because it surely avoids warnings anyhow.:)
If I decided to ask a new question, I'll update this question to add a link.
According to the C++ grammar, expressions (apart from lambda expressions perhaps, but that's a different story) cannot contain statements - including block statements. Therefore, I would say your code is ill-formed, and if GCC compiles it, it means this is a (strange) compiler extension.
You should consult the compiler's reference to figure out what semantics it is given (or not given, as the error message seems to suggest) to it.
EDIT:
As pointed out by Shafik Yaghmour in the comments, this appears to be a GNU extension. According to the documentation, the value of this "statement expression" is supposed to be the value of the last statement in the block, which should be an expression statement:
The last thing in the compound statement should be an expression followed by a semicolon; the value of this subexpression serves as the value of the entire construct. (If you use some other kind of statement last within the braces, the construct has type void, and thus effectively no value.)
Since the block in your example does not contain an expression statement as the last statement, GCC does not know how to evaluate that "statement expression" (not to be confused with "expression statement" - that's what should appear last in a statement expression).
To prevent GCC from complaining, therefore, you should do something like:
({if (a) a=0; a;});
// ^^
But honestly, I do not understand why one would ever need this thing in C++.
I came across this code recently, which doesn't look legal to me (but gcc compiles it). I don't so much mind the construction as want a name for it:
#define MAX(a,b) \
({ \
typeof(a) _a = (a); \
typeof(b) _b = (b); \
(_a > _b) ? (_a) : (_b); \
})
Apparently, the last statement's value is being returned as the "value" of the expression bounded by the namespace.
Edit: Thanks for the answers guys. Turns out this is an extension to plain C called Statement Expressions.
It is not a namespace, it is a macro which returns maximum of two values.
\ at the end of the statements is use to append multiple statements and create a multi-line macro.
The code is not standard C++ but it compiles in gcc because it is supported as an gcc compiler extension.
Good Read:
Statement Expressions:
A compound statement is a sequence of statements enclosed by braces. In GNU C, a compound statement inside parentheses may appear as an expression in what is called a Statement expression.
.--------------.
V |
>>-(--{----statement--;-+--}--)--------------------------------><
The value of a statement expression is the value of the last simple expression to appear in the entire construct. If the last statement is not an expression, then the construct is of type void and has no value.
Note: This excerpt is taken from IBM XL C/C++ v7.0 documentation.
This is called a statement expression, and is a non-standard extension of GCC. It allows you to use a compound statement as an expression, with a value given by the last expression in the compound statement.
It's used here to avoid the problem that function-like macros may evaluate their arguments multiple times, giving unexpected behaviour if those evaluations have side-effects. The macro is carefully written to evaluate a and b exactly once.
In C++, you should never need to do anything like this - use function templates instead:
template <typename T> T max(T const & a, T const & b) {
return a > b ? a : b;
}
First of all, it is not Standard C++, because typeof is an extension to C++, by GCC. There is another extension, called Statement Extension is used in the code.
Compile your code with -pedantic option, it will not compile.
As for the question, it is not namespace. It is just a macro, which gives you maximum of two values.
This a macro, just like any other #DEFINE. Essentially, the compiler replaces MAX(a,b) with the code defined therein. This will return the max value.
The {} operators, in this context, are an "anonymous scope operator" (aka "lexical enclosure," "form," and various other things. They're being used, somewhat akin to a namespace, to limit the scope of _a and _b to within the braces, so they won't conflict with other vars you might have with the same names. "auto" vars defined within the {braces} will be "destroyed" after the closing brace is reached; or, on a non-local transfer, like a "return" or "longjmp". You can't, however, reliably use "goto" to broach them.
You're probably only used to seeing them after "if," "do," "while," and "for" operators, but think of it as a way to generally "bundle" multiple statements into one "slot," just as you would to run multiple statements as the "then" or "else" clause of an "if" (where, leaving out the braces, you have only one statement "slot")
As Mike Seymour pointed out, the ({}) operation is a non-standard GCC extension, which returns the value of the last item evaluated within it. It's very similar to the general scoping operator, except the inherent return at the end.
This may be seen as off topic, but the title of this question came up in my web search while looking for a way to return a value from a {} block. Then I realized how to do it from standard c++ constructs. I post this for the next person who lands here for the same reason.
To pick up on what #BRPocock said, lo these 8 years ago, it is possible to return a value from a “anonymous scope operator” / “lexical enclosure” — hence use a {} block as part of an expression — through the use of lambda functions.
(Historical aside: all of the binding forms in Lisp can be written in terms of macros using lambda expressions. Lisp is where the modern term “lambda function” comes from. Lisp was John McCarthy's 1959 procedural embodiment of the theoretical “lambda calculus” of Church and Turning.)
Back to c++, this is a minimal anonymous lambda function, with no lexical capture, no arguments, and an empty body:
[](){}
This is that function applied to no arguments:
[](){}()
Here is that function call with some statements in its body:
[](){ int i=2; int j=3; return i+j; }()
There is some extra “stuff” around it (which could be encapsulated with a macro) and it requires explicit use of return, but it meets the basic functionality of returning a value from a {} block. For example this will print 5:
std::cout << [](){ int i=2; int j=3; return i+j; }() << std::endl;
I came across this weird C++ program.
#include <iostream>
using namespace std;
int main()
{
int a = ({int x; cin >> x; x;});
cout << a;
}
Can anyone explain what is going on? What is this construct called?
It assigns user input value to a and prints it out. it is done by using a Statement Expression.
Statement Expressions are a gnu gcc compiler extension and are not supported by the C/C++ standards. Hence, any code which uses statement expression is not standard conforming and non-portable.
The IBM XL C/C++ v7.0 also support Statement Expressions & its documentation explains them aptly:
Statement Expressions:
A compound statement is a sequence of statements enclosed by braces. In GNU C, a compound statement inside parentheses may appear as an expression in what is called a Statement expression.
.--------------.
V |
>>-(--{----statement--;-+--}--)--------------------------------><
The value of a statement expression is the value of the last simple expression to appear in the entire construct. If the last statement is not an expression, then the construct is of type void and has no value.
Always compile your code by selecting a standard in GCC: use one of the options -ansi, -std=c90 or -std=iso9899:1990, -std=c++03, -std=c++0x; to obtain all the diagnostics required by the standard, you should also specify -pedantic (or -pedantic-errors if you want them to be errors rather than warnings).
It's a GCC extension. Compile your code with the -pedantic flag if you want to get rid of stuff like this (and you really do want to).
It creates an inline scope, declares x within it, reads it from the standard input and the whole statement finally evaluates to x, which is assigned to a.
The comma operator works similarly, although it doesn't require a separate scope. For example:
int x;
int a = (cin >> x, x);
would do the same. All the statements connected with commas will be executed sequentially, and the result of the whole expression will be set to the value of the rightmost operand.
I don't believe that this is standard C++. It's probably a compiler-specific extension that allows an inner scope to evaluate to a value.