How do I use the conditional (ternary) operator? - c++

I've always wondered how to write the "A ? B : C" syntax in a C++ compatible language.
I think it works something like: (Pseudo code)
If A > B
C = A
Else
C = B
Will any veteran C++ programmer please help me out?

It works like this:
(condition) ? true-clause : false-clause
It's most commonly used in assignment operations, although it has other uses as well. The ternary operator ? is a way of shortening an if-else clause, and is also called an immediate-if statement in other languages (IIf(condition,true-clause,false-clause) in VB, for example).
For example:
bool Three = SOME_VALUE;
int x = Three ? 3 : 0;
is the same as
bool Three = SOME_VALUE;
int x;
if (Three)
x = 3;
else
x = 0;

It works like this:
expression ? trueValue : falseValue
Which basically means that if expression evaluates to true, trueValue will be returned or executed, and falseValue will be returned or evaluated if not.
Remember that trueValue and falseValue will only be evaluated and executed if the expression is true or false, respectively. This behavior is called short circuiting.

In c++ there's no actual if part of this. It's called the ternary operator. It's used like this: <boolean statement> ? <result if true> : <result if false>; For your example above it would look like this:
C = A > B ? A : B;
This article on wikipedia also discusses it:
http://en.wikipedia.org/wiki/Ternary_operation

I assume you mean stuff like a = b ? c : d, where b is the condition, c is the value when b is true, and d is the value when b is false.

I would say the ? is a short-cut. However, some "hard-core" programmers tend to say write it out the long way so in future cases, people can easily read and modify code.
For example, if you write
int a = b<c ? b : c;
Some people claim that it's clearer to write:
if(b<c)
a = b;
else
a = c;
Because in future cases, people can catch it. Of course, a simple b<c ? b:c is easy to catch, but sometimes complex operations are put in and it can be hard to spot.

No one seems to mention that a result of conditional operator expression can be an L-value in C++ (But not in C). The following code compiles in C++ and runs well:
int a, b;
bool cond;
a=1; b=2; cond=true;
(cond? a : b) = 3;
cout << a << "," << b << endl;
The above program prints 3, 2
Yet if a and b are of different types, it won't work. The following code gives a compiler error:
int a;
double b;
bool cond;
a=1; b=2; cond=true;
(cond? a : b) = 3;
cout << a << "," << b << endl;

IT IS QUITE SIMPLE
IT'S BASIC SYNTAX IS:
expression1?expression2:expression3;
If expression 1 is hold true then expression 2 will hold otherwise expression 3 will hold.
example:
hey=24>2?24:34;
here as condition is true value of 24 will be assigned to it.
if it was false then 34 will be assigned to it

simply you can write this as
C=(A>B)?A:B;
THIS IS SAME AS:
if(A>B)
C=A;
else
C=B;

This is called a "Ternary operator", and the ? and : are another way of writing an if-else statement.
Look at the "Example #1" in this Codepen, and un-comment it... you'll notice what it does.
Now comment "Example #1", un-comment "Example #2", and see what happens. The code does the exact same thing... but this time with only 5 lines of code. Notice how whatever appears before the ? sign is the if (conditional), and whatever comes AFTER the : is the thing to be executed.
But what if you have a conditional that requires an "else-if" (with more than 2 possible outcomes) like the one in the Codepen's "Example #3" (which adds the possibility of the user writing a specific wrong answer)? Then the ternary operator might not be as useful, but you can certainly concatenate several conditions with the ternary operator, like on this ES6 fizzbuzz example.

like this is our condition -> A?B:C
So according to the condition if 'A' is True then it prints 'B' or if 'A' is false it prints 'C'.
In other words we can also say that it is an alternative way of if else condition.

Related

What does '?' mean in this statement of C++? [duplicate]

I've always wondered how to write the "A ? B : C" syntax in a C++ compatible language.
I think it works something like: (Pseudo code)
If A > B
C = A
Else
C = B
Will any veteran C++ programmer please help me out?
It works like this:
(condition) ? true-clause : false-clause
It's most commonly used in assignment operations, although it has other uses as well. The ternary operator ? is a way of shortening an if-else clause, and is also called an immediate-if statement in other languages (IIf(condition,true-clause,false-clause) in VB, for example).
For example:
bool Three = SOME_VALUE;
int x = Three ? 3 : 0;
is the same as
bool Three = SOME_VALUE;
int x;
if (Three)
x = 3;
else
x = 0;
It works like this:
expression ? trueValue : falseValue
Which basically means that if expression evaluates to true, trueValue will be returned or executed, and falseValue will be returned or evaluated if not.
Remember that trueValue and falseValue will only be evaluated and executed if the expression is true or false, respectively. This behavior is called short circuiting.
In c++ there's no actual if part of this. It's called the ternary operator. It's used like this: <boolean statement> ? <result if true> : <result if false>; For your example above it would look like this:
C = A > B ? A : B;
This article on wikipedia also discusses it:
http://en.wikipedia.org/wiki/Ternary_operation
I assume you mean stuff like a = b ? c : d, where b is the condition, c is the value when b is true, and d is the value when b is false.
I would say the ? is a short-cut. However, some "hard-core" programmers tend to say write it out the long way so in future cases, people can easily read and modify code.
For example, if you write
int a = b<c ? b : c;
Some people claim that it's clearer to write:
if(b<c)
a = b;
else
a = c;
Because in future cases, people can catch it. Of course, a simple b<c ? b:c is easy to catch, but sometimes complex operations are put in and it can be hard to spot.
No one seems to mention that a result of conditional operator expression can be an L-value in C++ (But not in C). The following code compiles in C++ and runs well:
int a, b;
bool cond;
a=1; b=2; cond=true;
(cond? a : b) = 3;
cout << a << "," << b << endl;
The above program prints 3, 2
Yet if a and b are of different types, it won't work. The following code gives a compiler error:
int a;
double b;
bool cond;
a=1; b=2; cond=true;
(cond? a : b) = 3;
cout << a << "," << b << endl;
IT IS QUITE SIMPLE
IT'S BASIC SYNTAX IS:
expression1?expression2:expression3;
If expression 1 is hold true then expression 2 will hold otherwise expression 3 will hold.
example:
hey=24>2?24:34;
here as condition is true value of 24 will be assigned to it.
if it was false then 34 will be assigned to it
simply you can write this as
C=(A>B)?A:B;
THIS IS SAME AS:
if(A>B)
C=A;
else
C=B;
This is called a "Ternary operator", and the ? and : are another way of writing an if-else statement.
Look at the "Example #1" in this Codepen, and un-comment it... you'll notice what it does.
Now comment "Example #1", un-comment "Example #2", and see what happens. The code does the exact same thing... but this time with only 5 lines of code. Notice how whatever appears before the ? sign is the if (conditional), and whatever comes AFTER the : is the thing to be executed.
But what if you have a conditional that requires an "else-if" (with more than 2 possible outcomes) like the one in the Codepen's "Example #3" (which adds the possibility of the user writing a specific wrong answer)? Then the ternary operator might not be as useful, but you can certainly concatenate several conditions with the ternary operator, like on this ES6 fizzbuzz example.
like this is our condition -> A?B:C
So according to the condition if 'A' is True then it prints 'B' or if 'A' is false it prints 'C'.
In other words we can also say that it is an alternative way of if else condition.

C++: What does "a?b:c" means? [duplicate]

I've always wondered how to write the "A ? B : C" syntax in a C++ compatible language.
I think it works something like: (Pseudo code)
If A > B
C = A
Else
C = B
Will any veteran C++ programmer please help me out?
It works like this:
(condition) ? true-clause : false-clause
It's most commonly used in assignment operations, although it has other uses as well. The ternary operator ? is a way of shortening an if-else clause, and is also called an immediate-if statement in other languages (IIf(condition,true-clause,false-clause) in VB, for example).
For example:
bool Three = SOME_VALUE;
int x = Three ? 3 : 0;
is the same as
bool Three = SOME_VALUE;
int x;
if (Three)
x = 3;
else
x = 0;
It works like this:
expression ? trueValue : falseValue
Which basically means that if expression evaluates to true, trueValue will be returned or executed, and falseValue will be returned or evaluated if not.
Remember that trueValue and falseValue will only be evaluated and executed if the expression is true or false, respectively. This behavior is called short circuiting.
In c++ there's no actual if part of this. It's called the ternary operator. It's used like this: <boolean statement> ? <result if true> : <result if false>; For your example above it would look like this:
C = A > B ? A : B;
This article on wikipedia also discusses it:
http://en.wikipedia.org/wiki/Ternary_operation
I assume you mean stuff like a = b ? c : d, where b is the condition, c is the value when b is true, and d is the value when b is false.
I would say the ? is a short-cut. However, some "hard-core" programmers tend to say write it out the long way so in future cases, people can easily read and modify code.
For example, if you write
int a = b<c ? b : c;
Some people claim that it's clearer to write:
if(b<c)
a = b;
else
a = c;
Because in future cases, people can catch it. Of course, a simple b<c ? b:c is easy to catch, but sometimes complex operations are put in and it can be hard to spot.
No one seems to mention that a result of conditional operator expression can be an L-value in C++ (But not in C). The following code compiles in C++ and runs well:
int a, b;
bool cond;
a=1; b=2; cond=true;
(cond? a : b) = 3;
cout << a << "," << b << endl;
The above program prints 3, 2
Yet if a and b are of different types, it won't work. The following code gives a compiler error:
int a;
double b;
bool cond;
a=1; b=2; cond=true;
(cond? a : b) = 3;
cout << a << "," << b << endl;
IT IS QUITE SIMPLE
IT'S BASIC SYNTAX IS:
expression1?expression2:expression3;
If expression 1 is hold true then expression 2 will hold otherwise expression 3 will hold.
example:
hey=24>2?24:34;
here as condition is true value of 24 will be assigned to it.
if it was false then 34 will be assigned to it
simply you can write this as
C=(A>B)?A:B;
THIS IS SAME AS:
if(A>B)
C=A;
else
C=B;
This is called a "Ternary operator", and the ? and : are another way of writing an if-else statement.
Look at the "Example #1" in this Codepen, and un-comment it... you'll notice what it does.
Now comment "Example #1", un-comment "Example #2", and see what happens. The code does the exact same thing... but this time with only 5 lines of code. Notice how whatever appears before the ? sign is the if (conditional), and whatever comes AFTER the : is the thing to be executed.
But what if you have a conditional that requires an "else-if" (with more than 2 possible outcomes) like the one in the Codepen's "Example #3" (which adds the possibility of the user writing a specific wrong answer)? Then the ternary operator might not be as useful, but you can certainly concatenate several conditions with the ternary operator, like on this ES6 fizzbuzz example.
like this is our condition -> A?B:C
So according to the condition if 'A' is True then it prints 'B' or if 'A' is false it prints 'C'.
In other words we can also say that it is an alternative way of if else condition.

Understanding what this for loop will do [duplicate]

I've always wondered how to write the "A ? B : C" syntax in a C++ compatible language.
I think it works something like: (Pseudo code)
If A > B
C = A
Else
C = B
Will any veteran C++ programmer please help me out?
It works like this:
(condition) ? true-clause : false-clause
It's most commonly used in assignment operations, although it has other uses as well. The ternary operator ? is a way of shortening an if-else clause, and is also called an immediate-if statement in other languages (IIf(condition,true-clause,false-clause) in VB, for example).
For example:
bool Three = SOME_VALUE;
int x = Three ? 3 : 0;
is the same as
bool Three = SOME_VALUE;
int x;
if (Three)
x = 3;
else
x = 0;
It works like this:
expression ? trueValue : falseValue
Which basically means that if expression evaluates to true, trueValue will be returned or executed, and falseValue will be returned or evaluated if not.
Remember that trueValue and falseValue will only be evaluated and executed if the expression is true or false, respectively. This behavior is called short circuiting.
In c++ there's no actual if part of this. It's called the ternary operator. It's used like this: <boolean statement> ? <result if true> : <result if false>; For your example above it would look like this:
C = A > B ? A : B;
This article on wikipedia also discusses it:
http://en.wikipedia.org/wiki/Ternary_operation
I assume you mean stuff like a = b ? c : d, where b is the condition, c is the value when b is true, and d is the value when b is false.
I would say the ? is a short-cut. However, some "hard-core" programmers tend to say write it out the long way so in future cases, people can easily read and modify code.
For example, if you write
int a = b<c ? b : c;
Some people claim that it's clearer to write:
if(b<c)
a = b;
else
a = c;
Because in future cases, people can catch it. Of course, a simple b<c ? b:c is easy to catch, but sometimes complex operations are put in and it can be hard to spot.
No one seems to mention that a result of conditional operator expression can be an L-value in C++ (But not in C). The following code compiles in C++ and runs well:
int a, b;
bool cond;
a=1; b=2; cond=true;
(cond? a : b) = 3;
cout << a << "," << b << endl;
The above program prints 3, 2
Yet if a and b are of different types, it won't work. The following code gives a compiler error:
int a;
double b;
bool cond;
a=1; b=2; cond=true;
(cond? a : b) = 3;
cout << a << "," << b << endl;
IT IS QUITE SIMPLE
IT'S BASIC SYNTAX IS:
expression1?expression2:expression3;
If expression 1 is hold true then expression 2 will hold otherwise expression 3 will hold.
example:
hey=24>2?24:34;
here as condition is true value of 24 will be assigned to it.
if it was false then 34 will be assigned to it
simply you can write this as
C=(A>B)?A:B;
THIS IS SAME AS:
if(A>B)
C=A;
else
C=B;
This is called a "Ternary operator", and the ? and : are another way of writing an if-else statement.
Look at the "Example #1" in this Codepen, and un-comment it... you'll notice what it does.
Now comment "Example #1", un-comment "Example #2", and see what happens. The code does the exact same thing... but this time with only 5 lines of code. Notice how whatever appears before the ? sign is the if (conditional), and whatever comes AFTER the : is the thing to be executed.
But what if you have a conditional that requires an "else-if" (with more than 2 possible outcomes) like the one in the Codepen's "Example #3" (which adds the possibility of the user writing a specific wrong answer)? Then the ternary operator might not be as useful, but you can certainly concatenate several conditions with the ternary operator, like on this ES6 fizzbuzz example.
like this is our condition -> A?B:C
So according to the condition if 'A' is True then it prints 'B' or if 'A' is false it prints 'C'.
In other words we can also say that it is an alternative way of if else condition.

Can every if-else construct be replaced by an equivalent conditional expression?

(I don't have a serious need for this answer, I am just inquisitive.)
Can every if-else construct be replaced by an equivalent conditional expression using the conditional operator ?:?
Does every if-else constructs can be replaced by an equivalent conditional expression using conditional operator?
No, you've asked this backwards. The "bodies" of if/else contain statements, and it is not possible to turn every statement into an expression, such as try, while, break statements, as well as declarations. Many "statements" are really expressions in disguise, however:
++i;
blah = 42;
some_method(a,b,c);
All of these are statements which consist of one expression (increment, assignment, function-call, respectively) and could be turned into expressions within a conditional.
So, let's reverse the question, since it sounds like you really want to know how equivalent if/else statements are to ternary conditional expressions: Can every conditional expression be replaced by equivalent if/else statements? Almost all, yes. A common example is return statements:
return cond ? t : f;
// becomes:
if (cond) return t;
else return f;
But also other expressions:
n = (cond ? t : f);
// becomes:
if (cond) n = t;
else n = f;
Which starts to point to where conditional expressions cannot be easily replaced: initializations. Since you can only initialize an object once, you must break up an initialization that uses a conditional into using an explicit temporary variable instead:
T obj (cond ? t : f);
// becomes:
SomeType temp;
if (cond) temp = t;
else temp = f;
T obj (temp);
Notice this is much more tedious/cumbersome, and requires something type-dependent if SomeType cannot be default-constructed and assigned.
On the surface of it, no. The conditional operator is an expression (that is, it has a value), while if/else is a statement (thus has no value). They fulfill different "needs" within the language syntax.
However, since you can ignore expression values, and since any expression can be turned into a statement by adding a semicolon, you can essentially emulate if/else with a conditional expression and two auxiliary functions:
// Original code:
if (condition) {
// block 1
}
else {
// block 2
}
// conditional expression replacement:
bool if_block() {
// block 1
return true;
}
bool else_block() {
// block 2
return true;
}
// Here's the conditional expression. bool value discarded:
condition ? if_block() : else_block();
However, having said that, I'm not sure it's anything more than a curiosity...
No, of course not. For reasons already mentioned, and more!
#include <cstdlib>
#include <iostream>
int main()
{
if(int i = std::rand() % 2)
{
std::cout << i << " is odd" << std::endl;
}
else
{
std::cout << i << " is even" << std::endl;
}
}
Check out where is is declared. It's not an often used technique, but it can be used in situations like COM where every call returns HRESULT which is (almost always) zero on success (S_OK), non-zero on failure, so you might write something like:
if(HRESULT hr = myInterface->myMethod())
{
_com_raise_error(hr);
}
The ternary operator can't do anything analogous.
if( cond )
break;
else
a=b;
can not always be replaced by ?: operator. You can often (if not always) rethink your whole code to provide for this substitute, but generally you can't put anything that controls execution into ?:. break, return, loops, throw, etc.
In principle, yes:
if (A) B; else C
becomes
try {
A ? throw TrueResult() : throw FalseResult();
// or: throw A ? TrueResult() : FalseResult();
} catch (TrueResult) {
B;
} catch (FalseResult) {
C;
}
Compared to using procedures (which are more natural), this allows break, continue, return etc. It requires evaluation of A doesn't end with TrueResult/FalseResult but if you use those exceptions only to simulate if, it won't be a problem.
Using the conditional operator results in an expression and both potential results of the conditional operator must be 'compatible' (convertible to the same type).
An if-else construct need not even 'return' any type much less the same one from both branches.
The conditional operator expects to have both of the items following the ? be rvalues (since the result of a conditional operator is itself an rvalue) - so while I'm not entirely an expert on the C/C++ standards, my intuition would be that the following would be disallowed (or failing that, extremely poor coding style...):
(condition) ? return x : return y;
whereas the if-else version would be quite standard:
if(condition) return x;
else return y;
Now, that said, could you take any program and write a similarly functioning program that didn't use if-else? Sure, you probably could. Doesn't mean it would be a good idea, though. ;)
GCC has statement expression, using it you can rewrite if statements to equivalent ?: expressions:
if (<expression>)
<statement1>
else
<statement2>
EDIT: The void casts serves two purpose. The subexpressions in ?: must have the same type, and without the void cast the compiler may print warning: statement with no effect.
(<expression>)? (void)({<statement1>}) : (void)({<statement2>});

Uses of C comma operator [duplicate]

This question already has answers here:
What does the comma operator , do?
(8 answers)
Closed 8 years ago.
You see it used in for loop statements, but it's legal syntax anywhere. What uses have you found for it elsewhere, if any?
C language (as well as C++) is historically a mix of two completely different programming styles, which one can refer to as "statement programming" and "expression programming". As you know, every procedural programming language normally supports such fundamental constructs as sequencing and branching (see Structured Programming). These fundamental constructs are present in C/C++ languages in two forms: one for statement programming, another for expression programming.
For example, when you write your program in terms of statements, you might use a sequence of statements separated by ;. When you want to do some branching, you use if statements. You can also use cycles and other kinds of control transfer statements.
In expression programming the same constructs are available to you as well. This is actually where , operator comes into play. Operator , is nothing else than a separator of sequential expressions in C, i.e. operator , in expression programming serves the same role as ; does in statement programming. Branching in expression programming is done through ?: operator and, alternatively, through short-circuit evaluation properties of && and || operators. (Expression programming has no cycles though. And to replace them with recursion you'd have to apply statement programming.)
For example, the following code
a = rand();
++a;
b = rand();
c = a + b / 2;
if (a < c - 5)
d = a;
else
d = b;
which is an example of traditional statement programming, can be re-written in terms of expression programming as
a = rand(), ++a, b = rand(), c = a + b / 2, a < c - 5 ? d = a : d = b;
or as
a = rand(), ++a, b = rand(), c = a + b / 2, d = a < c - 5 ? a : b;
or
d = (a = rand(), ++a, b = rand(), c = a + b / 2, a < c - 5 ? a : b);
or
a = rand(), ++a, b = rand(), c = a + b / 2, (a < c - 5 && (d = a, 1)) || (d = b);
Needless to say, in practice statement programming usually produces much more readable C/C++ code, so we normally use expression programming in very well measured and restricted amounts. But in many cases it comes handy. And the line between what is acceptable and what is not is to a large degree a matter of personal preference and the ability to recognize and read established idioms.
As an additional note: the very design of the language is obviously tailored towards statements. Statements can freely invoke expressions, but expressions can't invoke statements (aside from calling pre-defined functions). This situation is changed in a rather interesting way in GCC compiler, which supports so called "statement expressions" as an extension (symmetrical to "expression statements" in standard C). "Statement expressions" allow user to directly insert statement-based code into expressions, just like they can insert expression-based code into statements in standard C.
As another additional note: in C++ language functor-based programming plays an important role, which can be seen as another form of "expression programming". According to the current trends in C++ design, it might be considered preferable over traditional statement programming in many situations.
I think generally C's comma is not a good style to use simply because it's so very very easy to miss - either by someone else trying to read/understand/fix your code, or you yourself a month down the line. Outside of variable declarations and for loops, of course, where it is idiomatic.
You can use it, for example, to pack multiple statements into a ternary operator (?:), ala:
int x = some_bool ? printf("WTF"), 5 : fprintf(stderr, "No, really, WTF"), 117;
but my gods, why?!? (I've seen it used in this way in real code, but don't have access to it to show unfortunately)
Two killer comma operator features in C++:
a) Read from stream until specific string is encountered (helps to keep the code DRY):
while (cin >> str, str != "STOP") {
//process str
}
b) Write complex code in constructor initializers:
class X : public A {
X() : A( (global_function(), global_result) ) {};
};
I've seen it used in macros where the macro is pretending to be a function and wants to return a value but needs to do some other work first. It's always ugly and often looks like a dangerous hack though.
Simplified example:
#define SomeMacro(A) ( DoWork(A), Permute(A) )
Here B=SomeMacro(A) "returns" the result of Permute(A) and assigns it to "B".
The Boost Assignment library is a good example of overloading the comma operator in a useful, readable way. For example:
using namespace boost::assign;
vector<int> v;
v += 1,2,3,4,5,6,7,8,9;
I had to use a comma to debug mutex locks to put a message before the lock starts to wait.
I could not but the log message in the body of the derived lock constructor, so I had to put it in the arguments of the base class constructor using : baseclass( ( log( "message" ) , actual_arg )) in the initialization list. Note the extra parenthesis.
Here is an extract of the classes :
class NamedMutex : public boost::timed_mutex
{
public:
...
private:
std::string name_ ;
};
void log( NamedMutex & ref__ , std::string const& name__ )
{
LOG( name__ << " waits for " << ref__.name_ );
}
class NamedUniqueLock : public boost::unique_lock< NamedMutex >
{
public:
NamedUniqueLock::NamedUniqueLock(
NamedMutex & ref__ ,
std::string const& name__ ,
size_t const& nbmilliseconds )
:
boost::unique_lock< NamedMutex >( ( log( ref__ , name__ ) , ref__ ) ,
boost::get_system_time() + boost::posix_time::milliseconds( nbmilliseconds ) ),
ref_( ref__ ),
name_( name__ )
{
}
....
};
From the C standard:
The left operand of a comma operator is evaluated as a void expression; there is a sequence point after its evaluation. Then the right operand is evaluated; the result has its type and value. (A comma operator does not yield an lvalue.)) If an attempt is made to modify the result of a comma operator or to access it after the next sequence point, the behavior is undefined.
In short it let you specify more than one expression where C expects only one. But in practice it's mostly used in for loops.
Note that:
int a, b, c;
is NOT the comma operator, it's a list of declarators.
It is sometimes used in macros, such as debug macros like this:
#define malloc(size) (printf("malloc(%d)\n", (int)(size)), malloc((size)))
(But look at this horrible failure, by yours truly, for what can happen when you overdo it.)
But unless you really need it, or you are sure that it makes the code more readable and maintainable, I would recommend against using the comma operator.
You can overload it (as long as this question has a "C++" tag). I have seen some code, where overloaded comma was used for generating matrices. Or vectors, I don't remember exactly. Isn't it pretty (although a little confusing):
MyVector foo = 2, 3, 4, 5, 6;
Outside of a for loop, and even there is has can have an aroma of code smell, the only place I've seen as a good use for the comma operator is as part of a delete:
delete p, p = 0;
The only value over the alternative is you can accidently copy/paste only half of this operation if it is on two lines.
I also like it because if you do it out of habit, you'll never forget the zero assignment. (Of course, why p isn't inside somekind of auto_ptr, smart_ptr, shared_ptr, etc wrapper is a different question.)
Given #Nicolas Goy's citation from the standard, then it sounds like you could write one-liner for loops like:
int a, b, c;
for(a = 0, b = 10; c += 2*a+b, a <= b; a++, b--);
printf("%d", c);
But good God, man, do you really want to make your C code more obscure in this way?
It's very useful in adding some commentary into ASSERT macros:
ASSERT(("This value must be true.", x));
Since most assert style macros will output the entire text of their argument, this adds an extra bit of useful information into the assertion.
In general I avoid using the comma operator because it just makes code less readable. In almost all cases, it would be simpler and clearer to just make two statements. Like:
foo=bar*2, plugh=hoo+7;
offers no clear advantage over:
foo=bar*2;
plugh=hoo+7;
The one place besides loops where I have used it it in if/else constructs, like:
if (a==1)
... do something ...
else if (function_with_side_effects_including_setting_b(), b==2)
... do something that relies on the side effects ...
You could put the function before the IF, but if the function takes a long time to run, you might want to avoid doing it if it's not necessary, and if the function should not be done unless a!=1, then that's not an option. The alternative is to nest the IF's an extra layer. That's actually what I usually do because the above code is a little cryptic. But I've done it the comma way now and then because nesting is also cryptic.
I often use it to run a static initializer function in some cpp files, to avoid lazy initalization problems with classic singletons:
void* s_static_pointer = 0;
void init() {
configureLib();
s_static_pointer = calculateFancyStuff(x,y,z);
regptr(s_static_pointer);
}
bool s_init = init(), true; // just run init() before anything else
Foo::Foo() {
s_static_pointer->doStuff(); // works properly
}
For me the one really useful case with commas in C is using them to perform something conditionally.
if (something) dothis(), dothat(), x++;
this is equivalent to
if (something) { dothis(); dothat(); x++; }
This is not about "typing less", it's just looks very clear sometimes.
Also loops are just like that:
while(true) x++, y += 5;
Of course both can only be useful when the conditional part or executable part of the loop is quite small, two-three operations.
The only time I have ever seen the , operator used outside a for loop was to perform an assingment in a ternary statement. It was a long time ago so I cannot remeber the exact statement but it was something like:
int ans = isRunning() ? total += 10, newAnswer(total) : 0;
Obviously no sane person would write code like this, but the author was an evil genius who construct c statements based on the assembler code they generated, not readability. For instance he sometimes used loops instead of if statements because he preferred the assembler it generated.
His code was very fast but unmaintainable, I am glad I don't have to work with it any more.
I've used it for a macro to "assign a value of any type to an output buffer pointed to by a char*, and then increment the pointer by the required number of bytes", like this:
#define ASSIGN_INCR(p, val, type) ((*((type) *)(p) = (val)), (p) += sizeof(type))
Using the comma operator means the macro can be used in expressions or as statements as desired:
if (need_to_output_short)
ASSIGN_INCR(ptr, short_value, short);
latest_pos = ASSIGN_INCR(ptr, int_value, int);
send_buff(outbuff, (int)(ASSIGN_INCR(ptr, last_value, int) - outbuff));
It reduced some repetitive typing but you do have to be careful it doesn't get too unreadable.
Please see my overly-long version of this answer here.
It can be handy for "code golf":
Code Golf: Playing Cubes
The , in if(i>0)t=i,i=0; saves two characters.
qemu has some code that uses the comma operator within the conditional portion of a for loop (see QTAILQ_FOREACH_SAFE in qemu-queue.h). What they did boils down to the following:
#include <stdio.h>
int main( int argc, char* argv[] ){
int x = 0, y = 0;
for( x = 0; x < 3 && (y = x+1,1); x = y ){
printf( "%d, %d\n", x, y );
}
printf( "\n%d, %d\n\n", x, y );
for( x = 0, y = x+1; x < 3; x = y, y = x+1 ){
printf( "%d, %d\n", x, y );
}
printf( "\n%d, %d\n", x, y );
return 0;
}
... with the following output:
0, 1
1, 2
2, 3
3, 3
0, 1
1, 2
2, 3
3, 4
The first version of this loop has the following effects:
It avoids doing two assignments, so the chances of the code getting out of sync is reduced
Since it uses &&, the assignment is not evaluated after the last iteration
Since the assignment isn't evaluated, it won't try to de-reference the next element in the queue when it's at the end (in qemu's code, not the code above).
Inside the loop, you have access to the current and next element
Found it in array initialization:
In C what exactly happens if i use () to initialize a double dimension array instead of the {}?
When I initialize an array a[][]:
int a[2][5]={(8,9,7,67,11),(7,8,9,199,89)};
and then display the array elements.
I get:
11 89 0 0 0
0 0 0 0 0