4
#include <iostream>

struct A {
    int x;
};

void foo(A a) {
    std::cout << a.x << std::endl;
}

int main() {
    A a;
    foo(a);  // -7159156; a was default-initialized
    foo(A());  // 0; a was value-initialized
}

Is it possible to pass an rvalue of type A to foo() without value-initializing it? Do we have to use either value-initialization or an lvalue?

What's the point of avoiding value-initialization when it "costs" no more than ten nanoseconds, you may ask. How about a situation like this: we are hunting for a bug in an legacy app caused by an uninitialized memory access with valgrind, and zero is NOT considered as a valid value for the app. Value initialization will prevent valgrind to spot the location of uninitialized memory access.

You may say printing an uninitialized value is an UB but my "real" use case is not limited to printing. My question should remain valid without it.

nodakai
  • 7,773
  • 3
  • 30
  • 60
  • Do uninitialized class members have defined behavior? – πάντα ῥεῖ Oct 12 '16 at 08:38
  • 2
    Does `A` have to tick all the boxes for being a POD? If you can give it an empty user-provided default constructor, then value-initialization becomes effectively equivalent to default-initialization, and you get your desired undefined behaviour ;-). – bogdan Oct 12 '16 at 08:58
  • @bogdan `A` could be out of my control. Eg. `struct tm` – nodakai Oct 12 '16 at 09:00
  • 2
    @nodakai But can you control the call site? If yes, you could wrap it into another `struct B { B() { } A m; };` and do `foo(B().m);`. `B().m` is an xvalue, not a prvalue as `A()`, but still an rvalue. – bogdan Oct 12 '16 at 09:06

1 Answers1

1

If i understand the question correctly you need a replacement for foo(A()); or similar cases where A() is called so that you don't have default initialization of members.

In that case one here is what i came up with:

  • First i tried to add A() = default (but this might not work with older c++ standards) and i had interesting results. The exact sample you provided works in reverse printing first 0 and then some random number.

  • Second i did not use A() = default; and just used a templated function

    template <class T> T make() { T tmp; return tmp; }
    

    At the cost of a copy (or move) you can use it like foo(make<A>()) and get the result you wanted.

Raxvan
  • 6,257
  • 2
  • 25
  • 46