55

I want to use ternary operator without else in C. How do I do it.

(a)? b: nothing;

something like this. What do I use in nothing part?

Jeyaram
  • 9,158
  • 7
  • 41
  • 63
user437777
  • 1,423
  • 4
  • 17
  • 28
  • 17
    why use a ternary operator if you are not going to use else. It loses the purpose of it. – Daniel Casserly Sep 04 '12 at 09:45
  • 1
    i got the same question as op, `cout << ((isNegative) ? '-') << number` would be a perfect example of where you would want an extra character when a certain condition is true, and the else cannot be '', because a character cannot be empty. –  May 13 '17 at 12:17
  • What is it meant to mean, and in what context do you want to use it? – PJTraill Feb 09 '19 at 09:39
  • @user5887651 One could use `(isNegative ? (cout<<',') : cout) << number;` I suppose... – Mooing Duck Apr 01 '21 at 17:59
  • maybe OP wanted to use the ternary operator as an expression, but it's quite interesting to think "so, what is *'nothing'* expression?" – starriet Sep 28 '22 at 01:24

11 Answers11

58

If you are using a ternary operator like that, presumably it could be replaced by:

if (a) { b; }

which is much, much better. (The intent is clearer, so the code is easier to read, and there will be no performance loss.)

However, if you are using the ternary operator as an expression, i.e.

printf("%d cat%s", number_of_cats, number_of_cats != 1 ? "s" : <nothing>);

a = b*c + (d == 0 ? 1 : <nothing>);

then the <nothing> value depends on the context it is being used in. In my first example, <nothing> should be "", and in the second it should be 0.

huon
  • 94,605
  • 21
  • 231
  • 225
  • suppose I need to call other macros depending on conditions and last else part doing nothing, can I write something like below (Assume A,B,C are defined elsewhere): #define setValue(inp) (inp==A)?macro1():(inp==B)?macro2() :(inp==C)?macro3():0. But here again if 0 is the valid return on other macros, we may have issues. – Jon Wheelock Apr 14 '16 at 13:11
  • @JonWheelock: Just use multiline macros and `if` statements – Mooing Duck Apr 01 '21 at 18:00
29

An omitted false expression is invalid. Try reversing the condition instead.

(!a) ?: b;
GOSteen
  • 307
  • 3
  • 2
  • 21
    Note that `?:` without the second operand is a GNU extension. The semantics probably don't provide an answer to the question, as the value of the first operand (`!a`) will be used if non-false, and that of the third operand (`b`) otherwise. Because of `!`, that would always be `true` (technically a non-zero value) if `a` is false, whereas the OP wants "nothing". – tne Apr 09 '14 at 10:21
15

if-else is a control flow construct wheras ?: is an operator, and x ? y : z is an expression - an expression cannot have "no value", while control flow can have a "do nothing path". There is no real equivalence between if-else and ?: - they are not interchangeable in all circumstances.

You can achieve the effect you want in some circumstances, but it is probably less efficient that using if without else. For example the effect of:

if( x )
{
    y = z ;
}

can be achieved by:

y = x ? z : y ;

but there is an effective but redundant else y = y assignment when x is false which your compiler may or may not optimise out. So you can achieve the effect but only if you know the "current value" to return as the ?: expression result.

Clifford
  • 88,407
  • 13
  • 85
  • 165
4

You can't omit the else part. Just use a none expression.

But, in that case, it is often better to use an if...

md5
  • 23,373
  • 3
  • 44
  • 93
  • HI thanks for reply. It complies now. I understood 0 but dont understand what (void) indicate to the compiler? – user437777 Sep 04 '12 at 09:46
  • This necessitates that `b` also be of type `void`. – Alexey Frunze Sep 04 '12 at 09:47
  • I thought ternary operator is faster than if condition? Am I wrong? – user437777 Sep 04 '12 at 09:48
  • @user437777, not really. It's still an `if`, except more compact. More importantly, it's an expression that can be used inside other expressions. Otherwise, it's still just an `if`. – Shahbaz Sep 04 '12 at 09:49
  • Uhm, it is sometimes a little bit faster, but it's moot and irrelevant in mainly programs. – md5 Sep 04 '12 at 09:49
  • @userXXX it's a typecast - casting to void means 'throw away the result of the expression'. –  Sep 04 '12 at 09:49
  • Thanks all for reply. So I can use like (a)? (void)b:(void)0; about the speed, this condition is used about 2^16 times inside my code, will it be helpful to use ternary then? – user437777 Sep 04 '12 at 09:51
  • 3
    @user437777, the if and the ternary are likely to get compiled to the same code. – huon Sep 04 '12 at 09:53
  • 1
    Benchmark? It depends on the situation, and on the optimization level. – md5 Sep 04 '12 at 09:53
3

Seems this question has been around for a while, but FWIW a short C program compiled with GCC 4.6.3 revealed the following:

  1. The following does not compile: a = a ? b:;. "error: expected expression before ‘;’ token".
  2. The following is equivalent: a = a ?: b; and a = a ? a : b;

Perhaps someone can add more compiler-side details, but to me it seems that omitting the true execution path is just being fancy.

danns87
  • 1,020
  • 1
  • 9
  • 11
3

I tried putting any integers there and it works well. For example, if you want to return "a" if it's evaluated true, then you can write it like:

true ? a : 1;
Y.Du
  • 421
  • 4
  • 8
2

I did this

isLeapYear(i) ? cout<< i<<endl: cout<<"" ;

Not sure though, if there is any performance hit with this.

ngbtwby
  • 414
  • 4
  • 8
1

Ternary expressions base themselves on deriving statements from boolean conditions. If a statement is marked void() then as you expect, nothing happens.

C++ code:

condition ? add(value) : void();

C code:

condition ? add(value) : 0;
Tomerikoo
  • 18,379
  • 16
  • 47
  • 61
Rio Milano
  • 11
  • 1
1

If I knew that expression must be true, otherwise program is in invalid state, but ternary operator fits better than regular if() statement, I used to do like this

condition ? value : throw;

And leave it as above or add specific exception.

0

There are a variety of other forms a ? b : nothing; can be take.

Short circuit evaluation where b will only be evaluated if a is true:

a && b;

Ternary where the nothing expression is (void)0:

a ? b : (void)0;

Reversed ternary condition with a blank middle (may not be portable):

!a ? : b;

A simple if statement:

if (a) {
    b;
}
Ace.C
  • 1,201
  • 12
  • 22
-10

Try this

BOOL bIsOK = (a == 5)?TRUE:FALSE;
Taryn
  • 242,637
  • 56
  • 362
  • 405
Riskhan
  • 4,434
  • 12
  • 50
  • 76