42

Typically the '?' operator is used in the following form:

A ? B : C

However in cases where B = A I have seen the following abbreviation

A ? : C

This surprisingly works. Is it better to leave the second parameter in (style wise), or is their a chance certain compilers won't be able to handle this?

Dan Fego
  • 13,644
  • 6
  • 48
  • 59
Locksleyu
  • 5,192
  • 8
  • 52
  • 77
  • Looking like [Groovy](http://en.wikipedia.org/wiki/Groovy_%28programming_language%29)-like syntax. – Lion Apr 13 '12 at 15:24

6 Answers6

41

It is not permitted by the language C (as far as I know), but compilers such as gcc have the shortcut a?:c as an extension. a?:c means the same as a?a:c.

undur_gongor
  • 15,657
  • 5
  • 63
  • 75
Juri Robl
  • 5,614
  • 2
  • 29
  • 46
17

Its a gcc's extension

Conditionals with Omitted Operands

x ? : y is equivalent to x ? x : y

Prasoon Saurav
  • 91,295
  • 49
  • 239
  • 345
  • 2
    The page you linked to contradicts itself. On the one hand it says "This example is perfectly equivalent to `x ? x : y`", which means `x` is evaluated twice, but on the other hand the last paragraph states that `x` would be evaluated only once, which would make it perfectly equivalent to `x || y`, not `x ? x : y` – Celada Apr 13 '12 at 15:03
  • 1
    @Celada : I think it means to say that `x ? : y` is **roughly** equivalent to `x ? x : y` except `x` gets evaluated only once in the former case. – Prasoon Saurav Apr 13 '12 at 15:05
  • 3
    @Celada : `x || y` evaluates to 0 or 1 which is not the case with this operator. – Prasoon Saurav Apr 13 '12 at 15:07
  • 1
    I stand corrected. I thought `||` returned value value of its first argument if the first argument was something that is considered true (nonzero). – Celada Apr 13 '12 at 15:12
  • It's one of ISO C99 features. It works fine for me on `GCC` 4.4.1 and `TCC`(that's an ANSI C compiler) version 0.9.25 on Windows plataform. – Jack Apr 13 '12 at 16:20
  • It works for Clang too, not only GCC. – 4LegsDrivenCat Dec 01 '21 at 20:05
3

Unless I'm badly mistake, you're using a compiler extension (at a guess, gcc). I'm pretty sure the standard does not allow you to omit the second operand to the ternary operator.

Jerry Coffin
  • 476,176
  • 80
  • 629
  • 1,111
3

I fill in a bit.

The standard uses the term conditional operator.

Syntax
  conditional-expression:
          logical-OR-expression
          logical-OR-expression ? expression : conditional-expression

A conditional expression does not yield an lvalue. Also; Wikipedia; Conditional

Note: I.e.: C++ has:
        logical-OR-expression ? expression : assignment-expression

Constraints:
* The first operand shall have scalar type[1].
* One of the following shall hold for the second and third operands:
   — both operands have arithmetic type[2];
   — both operands have the same structure[3] or union type[4];
   — both operands have void type[5];
   — both operands are pointers to qualified or unqualified[6] versions of compatible
     types[7];
   — one operand is a pointer and the other is a null pointer constant[8]; or
   — one operand is a pointer to an object or incomplete type[9] and the other 
     is a pointer to a qualified or unqualified version of void.

Foot food:

[1] Scalar type     : Arithmetic types and pointer types.
[2] Arithmetic type : Integer and floating types.
[3] Structure type  : A sequentially allocated nonempty set of member objects (and, in
                     certain circumstances, an incomplete array), each of which has an
                     optionally specified name and possibly distinct type.
[4] Union type      : An overlapping nonempty set of member objects, each of which has
                     an optionally specified name and possibly distinct type.
[5] Void type       : An empty set of values; it is an incomplete type that cannot be
                     completed.
[6] Qualified type  : 1998 (const and volatile), 1999 (restrict), respectively 
                     2011 (_Atomic). *
[7] Compatible type : Their types are the same.
[8] Null ptr. const.: NULL; implementation-defined null pointer constant.
[9] Incomplete type : Types that describe objects but lack information needed to determine 
                      their sizes.

* Type qualifiers in C

So: Not wise to use.

Morpfh
  • 4,033
  • 18
  • 26
1

i did a little research in the web, acording to wikipedia, this behavior is supported by a GNU extension of C. http://en.wikipedia.org/wiki/%3F:#C

So it is very probable that other compilers consider this illegal. By the way, this operator is called ternary conditional so you can browse about it.

EDIT:

I checked in gcc and apple llvm and it works fine.

LuisEspinoza
  • 8,508
  • 6
  • 35
  • 57
0

It is better to leave the second parameter in. If B ever changes, you may not remember to modify the statement above. Further, other people may have a difficult time reading your code and improving upon it if you leave B out of the statement.

Mike Foss
  • 311
  • 2
  • 6