7

I have some code which essentially boils down to the following:

void bar(bool b, double f)
{
    if (b){
        double g = f;
    }
}

void foo()
{
    double f;
    bool b = false;
    bar(b, f);
}

Is there any undefined behaviour here? I suspect there may be since I'm taking a value copy of the uninitialised double when passing f to bar. That said, I'm not making use of the passed double though since the if block will not run.

Furthermore, would everything be fine if I were to pass the double by reference:

void bar(bool b, double& f)

Then I'm not "using" an uninitialised variable but am simply referring to it.

2501
  • 25,460
  • 4
  • 47
  • 87
P45 Imminent
  • 8,319
  • 4
  • 35
  • 78
  • 5
    You don't have undefined behavior until you try to access the variable, and since that's done when passing it by value to the function you have undefined behavior in the call. If you instead pass by reference, then you have undefined behavior in the function when you then access the value of the reference. – Some programmer dude Dec 11 '14 at 11:12
  • "using a unitialized value is by itself not undefined behavior, but the value is simply indeterminate." (From [this answer](http://stackoverflow.com/a/11965368/96780)) – Daniel Daranas Dec 11 '14 at 11:13
  • 1
    @DanielDaranas *If the lvalue designates an object of automatic storage duration that could have been declared with the register storage class (never had its address taken), and that object is uninitialized (not declared with an initializer and no assignment to it has been performed prior to use), **the behavior is undefined.*** And that answer is referring to C btw. – 2501 Dec 11 '14 at 11:15
  • @DanielDaranas Trap representation was introduced by C99, I'm unsure if it applies to C++. – legends2k Dec 11 '14 at 11:17
  • @2501 Oops, I shouldn't have quoted an answer which refers to a different programming language. You're right - I just leave my previous comment for completeness. – Daniel Daranas Dec 11 '14 at 11:17
  • @DanielDaranas I'm fairly confident C++ says the same. – 2501 Dec 11 '14 at 11:20
  • 2
    @2501 And I'm even more confident that C++ doesn't. The suggestion to update the C++ standard to refer to trap representations resulted in a different update, with different words that have a different meaning. Particularly, in C++, reading uninitialised variables is *never* allowed for any type that is not an unsigned character type, regardless of whether the type in C would have trap representations. See [#616](http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#616). Even if a type *is* an unsigned character type, it's not unconditionally allowed, but only in some cases. –  Dec 11 '14 at 11:41
  • @hvd So you are saying it is undefined( that was my point ). – 2501 Dec 11 '14 at 11:41
  • @2501 Yes, and I'm saying that C++ follows different rules than C, that C++ is more strict about it. –  Dec 11 '14 at 11:43
  • It becomes undefined behavior [when a value is produced by an evaluation](http://stackoverflow.com/q/23415661/1708801), so the first case is undefined the second case is fine until unless you use `f` in an indeterminate state. – Shafik Yaghmour Dec 11 '14 at 14:15

1 Answers1

10

Yes, the behaviour is undefined. You are taking a value copy of the uninitialised double when passing it in the function parameter list.

Passing by reference is well-defined since all you're doing is binding that reference to that double. Of course, the behaviour of accessing that reference would be undefined.

N4140:

[dcl.init]

12 ... If an indeterminate value is produced by an evaluation, the behavior is undefined except in the following cases:

(Irrelevant text omitted, pertaining to unsigned narrow character types)

Bathsheba
  • 231,907
  • 34
  • 361
  • 483