What is this strange expression in GCC/Clang? - c++

I have recently noticed an strange valid C/C++ expression in GCC/Clang which I have never seen before. Here is the example in C++, but similar expression works in C too:
int main(){
int z = 5;
auto x = ({z > 3 ? 3 : 2;}); // <-- expression
std::cout << x;
}
What it does is somehow obvious, but I like to know what it is called. Since it does not worth in MSVC, I guess it is a non-standard extension. But is there anything that works for MSVC too? especially in C?

It's called statement expr, used in GCC. Your expression ({z > 3 ? 3 : 2;}) can be translated to
if (z > 3) {x = 3;} else {x = 2;}
From documentation:
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.
In other word, it provides the ability to put a compound statement in an expression position.
Related post :
Emulating GCC Statement Expressions
Use of ({ ... }) brackets in macros to swallow the semicolon

It is called conditional operator . Return will be depend on condition either condition is true or false.
But in this case:
auto x = ({z > 3 ? 3 : 2;}); // <-- expression
if Z is greater than 3 returns 3 otherwise 2.
Basic syntax : Expression1? expression2: expression3;

Related

Are comma separated statements considered full statements? (and other diagnostic issues)

I guess the answer is "no", but from a compiler point of view, I don't understand why.
I made a very simple code which freaks out compiler diagnostics quite badly (both clang and gcc), but I would like to have confirmation that the code is not ill formatted before I report mis-diagnostics. I should point out that these are not compiler bugs, the output is correct in all cases, but I have doubts about the warnings.
Consider the following code:
#include <iostream>
int main(){
int b,a;
b = 3;
b == 3 ? a = 1 : b = 2;
b == 2 ? a = 2 : b = 1;
a = a;
std::cerr << a << std::endl;
}
The assignment of a is a tautology, meaning that a will be initialized after the two ternary statements, regardless of b. GCC is perfectly happy with this code. Clang is slighly more clever and spot something silly (warning: explicitly assigning a variable of type 'int' to itself [-Wself-assign]), but no big deal.
Now the same thing (semantically at least), but shorter syntax:
#include <iostream>
int main(){
int b,a = (b=3,
b == 3 ? a = 1 : b = 2,
b == 2 ? a = 2 : b = 1,
a);
std::cerr << a << std::endl;
}
Now the compilers give me completely different warnings. Clang doesn't report anything strange anymore (which is probably correct because of the parenthesis precedence). gcc is a bit more scary and says:
test.cpp: In function ‘int main()’:
test.cpp:7:15: warning: operation on ‘a’ may be undefined [-Wsequence-point]
But is that true? That sequence-point warning gives me a hint that coma separated statements are not handled in the same way in practice, but I don't know if they should or not.
And it gets weirder, changing the code to:
#include <iostream>
int main(){
int b,a = (b=3,
b == 3 ? a = 1 : b = 2,
b == 2 ? a = 2 : b = 1,
a+0); // <- i just changed this line
std::cerr << a << std::endl;
}
and then suddenly clang realized that there might be something fishy with a:
test.cpp:7:14: warning: variable 'a' is uninitialized when used within its own initialization [-Wuninitialized]
a+0);
^
But there was no problem with a before... For some reasons clang cannot spot the tautology in this case. Again, it might simply be because those are not full statements anymore.
The problems are:
is this code valid and well defined (in all versions)?
how is the list of comma separated statements handled? Should it be different from the first version of the code with explicit statements?
is GCC right to report undefined behavior and sequence point issues? (in this case clang is missing some important diagnostics) I am aware that it says may, but still...
is clang right to report that a might be uninitialized in the last case? (then it should have the same diagnostic for the previous case)
Edit and comments:
I am getting several (rightful) comments that this code is anything but simple. This is true, but the point is that the compilers mis-diagnose when they encounter comma-separated statements in initializers. This is a bad thing. I made my code more complete to avoid the "have you tried this syntax..." comments. A much more realistic and human readable version of the problem could be written, which would exhibit wrong diagnostics, but I think this version shows more information and is more complete.
in a compiler-torture test suite, this would be considered very understandable and readable, they do much much worse :) We need code like that to test and assess compilers. This would not look pretty in production code, but that is not the point here.
5 Expressions
10 In some contexts, an expression only appears for its side effects. Such an expression is called a discarded-value
expression. The expression is evaluated and its value is discarded
5.18 Comma operator [expr.comma]
A pair of expressions separated by a comma is evaluated left-to-right;
the left expression is a discarded-value expression (Clause 5).83 Every
value computation and side effect associated with the left expression
is sequenced before every value computation and side effect associated
with the right expression. The type and value of the result are the
type and value of the right operand; the result is of the same value
category as its right operand, and is a bit-field if its right operand
is a glvalue and a bit-field.
It sounds to me like there's nothing wrong with your statement.
Looking more closely at the g++ warning, may be undefined, which tells me that the parser isn't smart enough to see that a=1 is guaranteed to be evaluated.

What is "from ?: first" In TextMate Source Code regexp.cc [duplicate]

I was writing a console application that would try to "guess" a number by trial and error, it worked fine and all but it left me wondering about a certain part that I wrote absentmindedly,
The code is:
#include <stdio.h>
#include <stdlib.h>
int main()
{
int x,i,a,cc;
for(;;){
scanf("%d",&x);
a=50;
i=100/a;
for(cc=0;;cc++)
{
if(x<a)
{
printf("%d was too big\n",a);
a=a-((100/(i<<=1))?:1);
}
else if (x>a)
{
printf("%d was too small\n",a);
a=a+((100/(i<<=1))?:1);
}
else
{
printf("%d was the right number\n-----------------%d---------------------\n",a,cc);
break;
}
}
}
return 0;
}
More specifically the part that confused me is
a=a+((100/(i<<=1))?:1);
//Code, code
a=a-((100/(i<<=1))?:1);
I used ((100/(i<<=1))?:1) to make sure that if 100/(i<<=1) returned 0 (or false) the whole expression would evaluate to 1 ((100/(i<<=1))?:***1***), and I left the part of the conditional that would work if it was true empty ((100/(i<<=1))? _this space_ :1), it seems to work correctly but is there any risk in leaving that part of the conditional empty?
This is a GNU C extension (see ?: wikipedia entry), so for portability you should explicitly state the second operand.
In the 'true' case, it is returning the result of the conditional.
The following statements are almost equivalent:
a = x ?: y;
a = x ? x : y;
The only difference is in the first statement, x is always evaluated once, whereas in the second, x will be evaluated twice if it is true. So the only difference is when evaluating x has side effects.
Either way, I'd consider this a subtle use of the syntax... and if you have any empathy for those maintaining your code, you should explicitly state the operand. :)
On the other hand, it's a nice little trick for a common use case.
This is a GCC extension to the C language. When nothing appears between ?:, then the value of the comparison is used in the true case.
The middle operand in a conditional expression may be omitted. Then if the first operand is nonzero, its value is the value of the conditional expression.
Therefore, the expression
    x ? : y
has the value of x if that is nonzero; otherwise, the value of y.
This example is perfectly equivalent to
    x ? x : y
In this simple case, the ability to omit the middle operand is not especially useful. When it becomes useful is when the first operand does, or may (if it is a macro argument), contain a side effect. Then repeating the operand in the middle would perform the side effect twice. Omitting the middle operand uses the value already computed without the undesirable effects of recomputing it.

macro hazards in c preprocessor

I have define the following macro,
#define abss(a) a >= 0 ? a : -a
while invoking this with,
int b=-1;
int c = abss(b);
printf("%d\n",c);
it should replaced in the form b >= 0 ? b : --b, which should output -2, but it outputs in my Bloodshed/DevC++ compiler 1.
I am analyzing C language for examination purpose, so I have to know what actually happens to the above case in C. Is the output result 1 is for CPP compiler I am using or what???
Your code
int b=-1;
int c = abss(b);
printf("%d\n",c);
gets translated by the preprocessor to:
int b=-1;
int c = b >= 0 ? b : -b;
printf("%d\n",c);
(the int b=-1 is in the C domain whereas the abss(b) gets expanded by the preprocessor before the compiler gets to int b=-1)
Why on earth do you think it should output -2?
#define abss(a) a >= 0 ? a : -a
so this:
int c = abss(b)
becomes
int c = b >= 0 ? b : -b
and b is -1, so that will evaluate to 1
by the way, you should bracket every use of a macro parameter, as you may get passed such things as x + 1. which would evaluate rather strangely.
Not to mention the results of abss(++x)
Your macro expands to
b >= 0 ? b : -b;
Not to b >= 0 ? b : --(-b); or whatever it is you expected.
Are you suggesting that
int x = -4;
-x;
should decrement x?
Bottom line - avoid macro use when possible.
The macro processor will never attach two adjacent tokens together, even if there is no whitespace between them, so indeed, as other posters have mentioned, your macro expands to - b, or 1.
If you want two tokens to become one when expanded by the preprocessor, you have to use the token pasting operator ##, something like
#define abss(a) a >= 0 ? a : - ## a
this will indeed do what you want, in the sense that the negative sign and the variable will form one token. Unfortunately (or fortunately, depending on how you look at it!) the pasted token "-b" will be invalid, and the expansion will not compile.
#define neg(a) -a
int b = -1;
neg(b);
In the above case, the macro is expanded to -b by the preprocessor, which will result in the value of 1. The preprocessor won't even be aware that the sign of the content of b is negative, so where should the second - come from to form a prefix decrement operator?
Even if you wrote it like this:
neg( -b );
Macro replacement is done on token level, not as a textual search & replace. You would get the equivalent of - ( -b ), but not --b.
Edit: The manual you link to in other comments is outdated (does not even address the C99 standard), and is dangerously bad. Just skimming through it I found half a dozen of statements that will make you look real stupid if you assume them to be correct. Don't use it, other than to light a fire.
This macro
#define abss(a) a >= 0 ? a : -a
is indeed hazardous, but the hazards are not where you think they are. The expression from your post
int c = abss(b);
works perfectly fine. However, consider what happens when the expression is not a simple variable, but is a function that is hard to calculate, or when it is an expression with side effects. For example
int c = abss(long_calc(arg1, arg2));
or
int c = abss(ask_user("Enter a value"));
or
int c = abss(b++);
If abss were a function, all three invocations would produce good results in predictable time. However, the macro makes the first call invoke long_calc and ask_user twice (what if the user enters a different number when prompted again?), and it post-increments b twice.
Moreover, consider this seemingly simple expression:
int c = abss(b) + 123;
Since + has a higher precedence than ? :, the resulting expansion will look like this:
int c = b >= 0 ? b : -b + 123;
When b is positive, 123 will not be added, so the meaning of the expression will change dramatically!
This last shortcoming can be addressed by enclosing the expression in parentheses. You should also enclose in parentheses each macro argument, like this:
#define abss(a) ((a) >= 0 ? (a) : -(a))
The reason for you getting the behaviour is preprocessor will just replace a with b and so effectively your code after preprocessing will be like
b >= 0 ? b : -b
and not
b >= 0 ? b : --b
So, when if b = -1, then it will effectively be considered as -(-1) and thus becomes 1.
You can check the preprocessor output and see it for yourself.

what's an expression and expression statement in c++?

I've read that usually statements in c++ end with a semi-colon; so that might help explain what an expression statement would be. But then what would you call an expression by giving an example?
In this case, are both just statements or expression statements or expressions?
int x;
x = 0;
An expression is "a sequence of operators and operands that specifies a computation" (that's the definition given in the C++ standard). Examples are 42, 2 + 2, "hello, world", and func("argument"). Assignments are expressions in C++; so are function calls.
I don't see a definition for the term "statement", but basically it's a chunk of code that performs some action. Examples are compound statements (consisting of zero or more other statements included in { ... }), if statements, goto statements, return statements, and expression statements. (In C++, but not in C, declarations are classified as statements.)
The terms statement and expression are defined very precisely by the language grammar.
An expression statement is a particular kind of statement. It consists of an optional expression followed by a semicolon. The expression is evaluated and any result is discarded. Usually this is used when the statement has side effects (otherwise there's not much point), but you can have a expression statement where the expression has no side effects. Examples are:
x = 42; // the expression happens to be an assignment
func("argument");
42; // no side effects, allowed but not useful
; // a null statement
The null statement is a special case. (I'm not sure why it's treated that way; in my opinion it would make more sense for it to be a disinct kind of statement. But that's the way the standard defines it.)
Note that
return 42;
is a statement, but it's not an expression statement. It contains an expression, but the expression (plus the ;) doesn't make up the entire statement.
These are expressions (remember math?):
1
6 * 7
a + b * 3
sin(3) + 7
a > b
a ? 1 : 0
func()
mystring + gimmeAString() + std::string("\n")
The following are all statements:
int x; // Also a declaration.
x = 0; // Also an assignment.
if(expr) { /*...*/ } // This is why it's called an "if-statement".
for(expr; expr; expr) { /*...*/ } // For-loop.
A statement is usually made up of an expression:
if(a > b) // a > b is an expr.
while(true) // true is an expr.
func(); // func() is an expr.
To understand what is an expression statement, you should first know what is an expression and what is an statement.
An expression in a programming language is a combination of one or more explicit values, constants, variables, operators, and functions that the programming language interprets (according to its particular rules of precedence and of association) and computes to produce ("to return", in a stateful environment) another value. This process, as for mathematical expressions, is called evaluation.
Source: https://en.wikipedia.org/wiki/Expression_(computer_science)
In other words expressions are a sort of data items. They can have single or multiple entities like constants and variables. These entities may be related or connected to each other by operators. Expressions may or may not have side effects, in that they evaluate to something by means of computation which changes a state. For instance numbers, things that look like mathematical formulas and calculations, assignments, function calls, logical evaluations, strings and string operations are all considered expressions.
function calls: According to MSDN, function calls are considered expressions. A function call is an expression that passes control and arguments (if any) to a function and has the form:
expression (expression-list opt) which is invoked by the ( ) function operator.
source: https://msdn.microsoft.com/en-us/library/be6ftfba.aspx
Some examples of expressions are:
46
18 * 3 + 22 / 2
a = 4
b = a + 3
c = b * -2
abs(c)
b >= c
c
"a string"
str = "some string"
strcat(str, " some thing else")
str2 = "some string" + " some other string" // in C++11 using string library
Statements are fragments of a program that execute in sequence and cause the computer to carry out some definite action. Some C++ statement types are:
expression statements;
compound statements;
selection statements;
iteration statements;
jump statements;
declaration statements;
try blocks;
atomic and synchronized blocks (TM TS).
Source: http://en.cppreference.com/w/cpp/language/statements
I've read usually statements in c++ ends with a semicon;
Yes usually! But not always. Consider the following piece of code which is a compound statement but does not end with a semicolon, rather it is enclosed between two curly braces:
{ // begining of a compound statement
int x; // A declaration statement
int y;
int z;
x = 2; // x = 2 is an expression, thus x = 2; with the trailing semicolon is an expression statement
y = 2 * x + 5;
if(y == 9) { // A control statement
z = 52;
} else { // A branching statement of a control statement
z = 0;
}
} // end of a compound statement
By now, as you might be guessing, an expression statement is any statement that has an expression followed by a semicolon. According to MSDN an expression statement is a statement that causes the expressions to be evaluated. No transfer of control or iteration takes place as a result of an expression statement.
Source: https://msdn.microsoft.com/en-us/library/s7ytfs2k.aspx
Some Examples of expression statements:
x = 4;
y = x * x + 10;
radius = 5;
pi = 3.141593;
circumference = 2. * pi * radius;
area = pi * radius * radius;
Therefore the following can not be considered expression statements since they transfer the control flow to another part of a program by calling a function:
printf("The control is passed to the printf function");
y = pow(x, 2);
side effects: A side effect refers to the modification of a state. Such as changing the value of a variable, writing some data on a disk showing a menu in the User Interface, etc.
Source: https://en.wikipedia.org/wiki/Side_effect_(computer_science)
Note that expression statements don't need to have side effects. That is they don't have to change or modify any state. For example if we consider a program's control flow as a state which could be modified, then the following expression statements
won't have any side effects over the program's control flow:
a = 8;
b = 10 + a;
k++;
Wheres the following expression statement would have a side effect, since it would pass the control flow to sqrt() function, thus changing a state:
d = sqrt(a); // The control flow is passed to sqrt() function
If we consider the value of a variable as a state as well, modifying it would be a side effect thus all of expression statements above have side effects, because they all modify a state. An expression statement that does not have any side effect is not very useful. Consider the following expression statements:
x = 7; // This expression statement sets the value of x to 7
x; // This expression statement is evaluated to 7 and does nothing useful
In the above example x = 7; is a useful expression statement for us. It sets the value of x to 7 by = the assignment operator. But x; evaluates to 7 and it doesn't do anything useful.
According to The C++ Programming Language by Bjarne Stroustrup Special(3rd) Edition, a statement is basically any declaration, function call, assignment, or conditional. Though, if you look at the grammar, it is much more complicated than that. An expression, in simple terms, is any math or logical operation(s).
The wikipedia links that ok posted in his answer can be of help too.
In my opinion,
a statement *states* the purpose of a code block. i.e. we say this block of code if(){} is an if-statement, or this x=42; is an expression statement. So code such as 42; serves no purporse, therefore, this is *not* a statement.
and,
an expression is any legal combination of symbols that represents a value (Credit to Webopedia); it combines variables and constants to produce new values(Quoted from Chapter 2 in The C Programming Language). Therefore, it also has a mathematical connotation. For instance, number 42 in x=42; is an expression (x=42; is not an expression but rather an expression statement), or func(x) is an expression because it will evaluate to something. On the contrary, int x; is not an expression because it is not representing any value.
I think this excerpt from a technical book is most useful and clear.
Read the paragraphs till the start of 1.4.2 statements would be useful enough.
An expression is "a sequence of operators and operands that specifies a computation"
These are expressions:
1
2 + 2
"hi"
cout << "Hello, World!"
The last one is indeed an expression; << is the output operator, cout (of type ostream) and "Hello, World!" (string literals) are the operands. The operator returns the left-hand operand, so (cout << "Hello, ") << "World!" is also a valid expression but also not a statement.
An expression becomes an expression statement when it is followed by a semicolon:
1;
2 + 2;
"hi";
cout << "Hello, World!";
An expression is part of a statement, OR a statement itself.
int x; is a statement and expression.
See this : http://en.wikipedia.org/wiki/Expression_%28programming%29
http://en.wikipedia.org/wiki/Statement_%28programming%29

C++ Conditional Operator

I once seen a -wired- operator in C++ which assigns value if greater than..
it was a combination of ?, < and =
e.g. let x = value if value is greater than x
I do not mean x=(x<value)x:value
It was some sort of x<?=value
But I can not remember it exactly, and can not find it online... Can some one remind me of it?
Thanks,
There is no operator that assigns variables based on their relative values.
However, there is the ?: operator:
x = value > x ? value : x;
If you read it out loud from left to right, it makes sense.
gcc has -- in version 3.3.6 at least! -- a gcc-specific language extension providing specialized operators for implementing min and max. Perhaps this is what you are thinking of?
Minimum and Maximum Operators in C++
I don't have gcc handy to test it with, but it might have an updating form, too.
How's that:
(x<value) || (x=value)
Are you thinking of the ternary operator?
result = a > b ? x : y;
I suspect what you're thinking of is a gcc extension1 that lets you leave out the middle operand to the conditional operator, so (for example):
a = b ? b : c;
can be written as:
a = b ?: c;
1 Despite the '2.95.3' in the URL, I'm not aware of a newer version of the linked page. If somebody is, please feel free to point it out (or edit it in).
it's a more convenient version of an if statement that is used for assignment
int x = (some bool) ? trueval : falseval;
this is roughly what it means, when the bool is evaluated it either gets the trueval or falseval depending on the outcome, it's easier than saying
int x;
if (someval)
x = trueval;
else
x = falseval;
x = x < value ? 0 : 1;
This function sets x to 0 is x < value, 1 otherwise.