4

I am working on big code base. While refactoring some code I found some strange behavior related to reference. Below is minimal code to explain my question.

#include <iostream>

int main() {
  // case 1
  {
    int start = 1;
    const int &eRef = start > 0 ? start : 9;
    start = 2;
    std::cout << start << eRef;
  }
  std::cout << std::endl;
  // case 2
  {
    int start = 1;
    int end = 9;
    const int &eRef = start > 0 ? start : end;
    start = 2;
    std::cout << start << eRef;
  }
  std::cout << std::endl;
  return 0;
}

Output of above code is

21

22

I am expecting output 22 for both case. But getting different output for both case.

It might be as per standard, but I would like to know reason behind it.

Community
  • 1
  • 1
Manthan Tilva
  • 3,135
  • 2
  • 17
  • 41
  • 2
    https://stackoverflow.com/questions/40167231/is-it-safe-to-create-a-const-reference-to-result-of-ternary-operator-in-c - I think this is a dup but haven't read through enough to confirm – Mat Sep 12 '18 at 12:31
  • The funny thing is when you remove the `> 0 ? start : 9;`, it behaves as expected. Maybe something with binding the reference to a literal has to do with it? – Fureeish Sep 12 '18 at 12:31
  • @Mat You're right, this is a duplicate. Short summary for the OP: `start > 0 ? start : 9` gives you an rvalue (and therefore a temporary object is created), `start > 0 ? start : end` gives you an lvalue. Also fun to think about is what happens with `start > 0 ? start : (const int &) 9`. –  Sep 12 '18 at 12:34
  • Solution: **don't use magic numbers**. Instead of `> 0 ? start : 9;` you should have introduces a `const int` of a value `9` and then proceed to evaluate the ternary operator. If you do: `int start = 1;const int literal9 = 9; const int &eRef = start > 0 ? start : literal9;`, everything works as expected – Fureeish Sep 12 '18 at 12:36
  • 4
    @Fureeish Are you serious? You're recommending a constant called `literal9`?? – Lightness Races in Orbit Sep 12 '18 at 12:37
  • @Pi It's "literally" stupid ;) – Lightness Races in Orbit Sep 12 '18 at 12:41
  • @LightnessRacesInOrbit well, are either you or OP recommending writing something similiar to the code in the original question in real code? Obviously not. I called it `literal9` just beacuse I had to come up with *some* name. The name should indicate what is the use of this variable. Tbh, if there is no justification to use any other name, one should consider whether the logic is not flawed – Fureeish Sep 12 '18 at 12:41
  • @Fureeish No, and where did I say that I recommended that? Your suggestion to replace the magic number with a constant is spot-on, but `literal9` is the worst way to do that (worse than the original approach). The name should describe the thing that is 9, not 9 itself. Your comment didn't say that. – Lightness Races in Orbit Sep 12 '18 at 12:42
  • And I didn't say I recommend such names. It's neither an answer nor a gudeline. It's a code that illustrates the idea with a potential fix and if you really want to waste your time arguing about a name of a variable in a comment, you are free to do so. If it really hurts your eyes, image there is a more convinient name :> – Fureeish Sep 12 '18 at 12:46

0 Answers0