Is this ternary conditional ?: correct (Objective) C syntax?

20,097

Solution 1

From http://en.wikipedia.org/wiki/%3F%3A

A GNU extension to C allows omitting the second operand, and using implicitly the first operand as the second also:

a = x ? : y;

The expression is equivalent to

a = x ? x : y;

except that if x is an expression, it is evaluated only once. The difference is significant if evaluating the expression has side effects.

Solution 2

This behaviour is defined for both gcc and clang. If you're building macOS or iOS code, there's no reason not to use it.

I would not use it in portable code, though, without carefully considering it.

Solution 3

This is a GNU C extension. Check you compiler settings (look for C flavor). Not sure if it's part of Clang, the only information I could get is in this page:

Introduction

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.

Solution 4

$ cat > foo.c
#include <stdio.h>

int main(int argc, char **argv)
{
  int b = 2;
  int c = 4;
  int a = b ?: c;
  printf("a: %d\n", a);
  return 0;
}
$ gcc -pedantic -Wall foo.c
foo.c: In function ‘main’:
foo.c:7: warning: ISO C forbids omitting the middle term of a ?: expression

So no, it's not allowed. What gcc emits in this case does this:

$ ./a.out 
a: 2

So the undefined behaviour is doing what you say in your question, even though you don't want to rely on that.

Share:
20,097

Related videos on Youtube

Ben
Author by

Ben

I've grown up a lot through using these sites and I have a lot of thoughts about how people can interact as individuals or groups in order to learn more and learn better. Some of these thoughts are scattered around the various meta sites.

Updated on July 09, 2022

Comments

  • Ben
    Ben almost 2 years

    I didn't think this was possible but apparently in Objective C it is allowed:

    int a = b ?: c;
    

    So you see what they're doing here, they're leaving out the second part of the ternary expression, such that if b is nonzero, b is used as the second part.

    It's clever but as far as I know this is against K&R C, and probably ANSI C.

    If not, I've been missing out of a terribly clever syntax trick for years...alas!

    Update: It is gcc.

    • Kerrek SB
      Kerrek SB over 12 years
      Which compiler? GCC has this as an extension, albeit a deprecated one.
    • Pubby
      Pubby over 12 years
      More correct term is conditional. Ternary just means it's an operator that takes 3 arguments.
  • Steven Fisher
    Steven Fisher over 12 years
    I don't love your use of the word "undefined" here. It would be better to call it nonstandard; the behaviour IS defined for GCC, just not for ISO C. That makes it undefined for other compilers and not portable, but it's still defined for GCC.
  • Admin
    Admin over 12 years
    @steven As the question was whether it's correct C syntax, then the fact that it's undefined behaviour in C is the correct answer regardless of what your compiler does.