1

Would it be possible to implement an if that checks for -1 and if not negative -1 than assign the value. But without having to call the function twice? or saving the return value to a local variable. I know this is possible in assembly, but is there a c implementation?

int i, x = -10;
if( func1(x) != -1) i = func1(x);
John Kugelman
  • 349,597
  • 67
  • 533
  • 578
user1539348
  • 513
  • 1
  • 7
  • 20
  • As-written `i` is in indeterminate (i.e. it has no defined value) without the function-call anyway, so what does it matter? `if ((i = func(x)) != -1) {/* use i */}` is just as good a value for `i` as anything else. – WhozCraig Feb 26 '13 at 03:14
  • shorter lines of C do not mean faster programs. You need to compare the assembly to see if there is anything gained. More often than not, these types of "optimizations" are not really optimizations, they are just confusing. – Josh Petitt Feb 26 '13 at 03:17
  • @JoshPetitt Suppose func1 performs some other side-effect, similar to rand. Would it still be an optimisation? – autistic Feb 26 '13 at 03:52
  • @modifiablelvalue, indeed, we could provide a clearer answer if we understood all of the reasons behind the restrictions OP describes. – Brian Cain Feb 26 '13 at 04:07
  • sorry for such a late response.... I was caught up in a class project. This is not for anything practical, it was just something that i stumbled on and was curious in how to implement. Since I couldn't find anything online, and it was bugging me. I know that the compiler could optimize it... but it seems to me others brought up the question of functions such as rand(). I suppose my question is more of a curiosty exercise. And thanks to all who posted, was very interesting to read – user1539348 Mar 09 '13 at 02:14

4 Answers4

2

saving the return value to a local variable

In my experience, avoiding local variables is rarely worth the clarity forfeited. Most compilers (most of the time) can often avoid the corresponding load/stores and just use registers for those locals. So don't avoid it, embrace it! The maintainer's sanity that gets preserved just might be your own.

I know this is possible in assembly, but is there a c implementation?

If it turns out your case is one where assembly is actually appropriate, make a declaration in a header file and link against the assembly routine.

Suggestion:

const int x = -10;
const int y = func1(x);
const int i = y != -1
            ? y
            : 0 /* You didn't really want an uninitialized value here, right? */ ;
Brian Cain
  • 14,403
  • 3
  • 50
  • 88
  • perhaps this is the only worthwhile use of ternary operator (i.e. being able to assign based on the comparison) – Josh Petitt Feb 26 '13 at 03:35
  • @JoshPetitt, I think it's probably the only use I've ever considered -- what's an example of abuse/misuse? – Brian Cain Feb 26 '13 at 03:38
  • 1
    when people use them instead of simple if statements because they think they are somehow faster because they can be written on one line. For instance if i already had a value. BTW, I'm not saying you did this. – Josh Petitt Feb 26 '13 at 03:39
  • @JoshPetitt Any language structure can be used to write poor code. Consider `goto`, `switch`, `struct`, `union` and `for (;;)`. All of these are welcome in situations where they improve the clarity of a solution, but they can all be misused to write horrible code. – autistic Feb 26 '13 at 04:00
  • @modifiablelvalue, agree 100% I think Brian showed how to use it in the one case it is best and what the OP was wanting? – Josh Petitt Feb 26 '13 at 05:11
  • @BrianCain, you reminded me of a little trickery I found in another SO question. See my edited answer, inspired by your answer :-) – Josh Petitt Feb 26 '13 at 05:28
  • @JoshPetitt The book entitled "21st Century C" uses the conditional operator to create a simple static assosciative array in example 10-7 (papersize.c from http://examples.oreilly.com/0636920025108/21st_century_examples.tgz). I think this is appropriate. – autistic Feb 26 '13 at 06:33
1

It depends whether or not func1 generates any side-effects. Consider rand(), or getchar() as examples. Calling these functions twice in a row might result in different return values, because they generate side effects; rand() changes the seed, and getchar() consumes a character from stdin. That is, rand() == rand() will usually1 evaluate to false, and getchar() == getchar() can't be predicted reliably. Supposing func1 were to generate a side-effect, the return value might differ for consecutive calls with the same input, and hence func1(x) == func1(x) might evaluate to false.

If func1 doesn't generate any side-effect, and the output is consistent based solely on the input, then I fail to see why you wouldn't settle with int i = func1(x);, and base logic on whether or not i == -1. Writing the least repetitive code results in greater legibility and maintainability. If you're concerned about the efficiency of this, don't be. Your compiler is most likely smart enough to eliminate dead code, so it'll do a good job at transforming this into something fairly efficient.

1. ... at least in any sane standard library implementation.

autistic
  • 1
  • 3
  • 35
  • 80
  • (not wanting to argue) but even with side effects, wouldn't int i = func1(x); make the most sense? It only calls the function once? BTW, I agree with your second paragraph wholeheartedly, side-effect or no side-effect. – Josh Petitt Feb 26 '13 at 12:57
  • @JoshPetitt: Supposing func1 generates side-effects, `if (func1(x) == -1) { i = func1(x); }` potentially generates twice as many side-effects as `int i = func1(x);`... just as `if (getchar() != -1) { i = getchar(); }` potentially consumes twice as many characters as `int i = getchar();`. – autistic Feb 26 '13 at 13:03
  • agreed, that's why I am saying call func1 once, not twice. I understand your concern about side effects. – Josh Petitt Feb 26 '13 at 14:23
  • Perhaps the OP wishes to discard the first side-effect, and only read the second one if the first results in -1? Seems odd, but you never know. – autistic Feb 26 '13 at 14:25
0
int c;
if((c = func1(x)) != -1) i = c;
Theodoros Chatzigiannakis
  • 28,773
  • 8
  • 68
  • 104
0

The best implementation I could think of would be:

int i = 0; // initialize to something
const int x = -10;
const int y = func1(x);

if (y != -1)
{
  i = y;
}

The const would let the compiler to any optimizations that it thinks is best (perhaps inline func1). Notice that func is only called once, which is probably best. The const y would also allow y to be kept in a register (which it would need to be anyway in order to perform the if). If you wanted to give more of a suggestion, you could do:

register const int y = func1(x);

However, the compiler is not required to honor your register keyword suggestion, so its probably best to leave it out.

EDIT BASED ON INSPIRATION FROM BRIAN'S ANSWER:

int i = ((func1(x) + 1) ?:0) - 1;

BTW, I probably wouldn't suggest using this, but it does answer the question. This is based on the SO question here. To me, I'm still confused as to the why for the question, it seems like more of a puzzle or job interview question than something that would be encountered in a "real" program? I'd certainly like to hear why this would be needed.

Community
  • 1
  • 1
Josh Petitt
  • 9,371
  • 12
  • 56
  • 104