0

I used to call functions which returns int error code or 0 on success like this:

int tmp = function_a() ?:
          function_b() ?:
          function_c();

if (tmp)
        handle_error();

Now I'm working on a project which -std=c90 -Wpedantic and I get:

warning: ISO C forbids omitting the middle term of a ?: expression [-Wpedantic]

Is there any good ISO C approach for this? I want to avoid this:

int tmp;

tmp = function_a();

if (tmp)
        handle_error();

tmp = function_b();

if (tmp)
        handle_error();

And this:

int tmp;

if ((tmp = function_a()))
       handle_error();

And mangling code with #define macros.

closed as off-topic by amon, Bart van Ingen Schenau, BobDalgleish, gnat, Machado Jan 28 at 17:35

This question appears to be off-topic. The users who voted to close gave this specific reason:

  • "Questions asking for assistance in explaining, writing or debugging code are off-topic here. These can be asked on Stack Overflow if they include the desired behavior, a specific problem or error, and the shortest code necessary to reproduce it in the question (see Minimal, Complete, and Verifiable Example)." – amon, BobDalgleish
If this question can be reworded to fit the rules in the help center, please edit the question.

  • 2
    Why are you using ?: in the first place? As long as you're using error return codes as booleans, you can just chain things with && or ||: int error_code = a() || b() || c(); – Kilian Foth Jan 25 at 9:12
  • @KilianFoth I can not. I want to know the error code. – Piotr Jedyk Jan 25 at 9:18
  • 1
    You should add that bit of information to the question. I was also going to suggest an approach that threw away the error code... – MetaFight Jan 25 at 10:28
  • What are you talking about? Since 0 signals success, composing calls with || does give you the error code. – Kilian Foth Jan 25 at 11:44
  • 1
    Please don't do any of this. Just do it the if-handle error way. Every other way suggested here will discourage proper error reporting later on and hurts debuggability. – idoby Jan 27 at 9:40
3

While you could use a temporary variable to save the result, you'd end up with something like:

int tmp;
tmp = (tmp = function_a()) ? tmp : ((tmp = function_b()) ? tmp : function_c());

Needless to say, don't do this. It is the equivalent of your old code, but is far less elegant. Even if it is more verbose, you should simply go with the more readable solution:

int tmp;
if(tmp = function_a()) {
    handle_error(tmp);
} else if (tmp = function_b()) {
    handle_error(tmp);
} else if (tmp = function_c()) {
    handle_error(tmp);
}

You could also write it like this, which perhaps would be a little more straightforward:

int tmp;
if((tmp = function_a()) || (tmp = function_b()) || (tmp = function_c())) {
    handle_error(tmp);
}
  • It's OK. But the first non-standard way is still most readable I think... – Piotr Jedyk Jan 25 at 9:48
  • @PiotrJedyk why? You've got a chained assignment to the same name. tmp = tmp = function_a() sounds like something a politician would say – Caleth Jan 25 at 11:27

Not the answer you're looking for? Browse other questions tagged or ask your own question.