7

I'm using this tutorial, but when I compile the code from it:

D3DXMatrixLookAtLH(
    &matView,
    &D3DXVECTOR3(0.0f, 10.0f, 0.0f), // warning C4238
    &D3DXVECTOR3(0.0f, 0.0f, 0.0f), // warning C4238
    &D3DXVECTOR3(0.0f, 0.0f, 1.0f) // warning C4238
);

I get:

warning C4238: nonstandard extension used : class rvalue used as lvalue

What is the proper (warningless) way of doing this without additional lines of code?

Also, I'm wondering what is so bad about that line of code? Why does it even give warning if it works just fine? Or does it...?

Lightness Races in Orbit
  • 378,754
  • 76
  • 643
  • 1,055
Rookie
  • 4,064
  • 6
  • 54
  • 86
  • 1
    Fact is, you can't take the address of a temporary (rvalue). `operator&` *needs* an lvalue. The warning correctly outlines that. However, practically speaking, the code is fine, since the temporaries will live until the end of the full expression (the function call). – Xeo Jan 06 '12 at 19:13
  • 2
    It gives the warning because the code isn't portable. Your compiler has an non-standard extension that allows it; other compilers might reject it. – Mike Seymour Jan 06 '12 at 19:18
  • The bad thing about it is that next time you'll by accident make `matView` a temporary as well. – lapk Jan 06 '12 at 19:22
  • @Xeo: Are temporaries referred-to only by rvalue expressions guaranteed to have storage? – Lightness Races in Orbit Jan 06 '12 at 19:26
  • @Lightness: I believe they are not allowed to be optimized away. – Xeo Jan 06 '12 at 19:28
  • 1
    BTW this is a perfect example of why you should _NOT completely trust_ arbitrary tutorials that you find on the internet. Stack Overflow answers are more trustworthy as they are peer-reviewed, and the reputation score of the answerer gives a fairly reliable indication of the answerer's prior peer-review success over a significant period of time. – Lightness Races in Orbit Jan 06 '12 at 19:29
  • @Xeo: I didn't ask whether they can be "optimized away". I asked whether they are guaranteed to have storage in the first place. – Lightness Races in Orbit Jan 06 '12 at 19:29
  • @Lightness: An object is a region of memory, as defined in the standard. As such, yes. – Xeo Jan 06 '12 at 19:32
  • 1
    @Xeo: Surely not all rvalue expressions refer to objects. Is `3` an object? `3` has no storage. Perhaps the reason that this is only a warning (not an error) is that the rvalue expression in _this_ case happens to refer to an object. – Lightness Races in Orbit Jan 06 '12 at 19:33
  • @LightnessRacesinOrbit This VC++ specific warning. _For compatibility with previous versions of Visual C++, Microsoft extensions (/Ze) allow you to use a class type as an rvalue in a context that implicitly or explicitly takes its address. In some cases, such as the example below, this can be dangerous._ Same code will not compile in VC++ with `/Za` switch (ANSI). – lapk Jan 06 '12 at 19:36
  • @Lightness: That's why I said "object". A `D3DXVECTOR3` is an object, and as such a region of memory. – Xeo Jan 06 '12 at 19:38

1 Answers1

16

You are taking the address of a temporary. You can't do that. Declare your vectors beforehand:

D3DXVECTOR3 a(0.0f, 10.0f, 0.0f)
            ,b(0.0f, 0.0f, 0.0f)
            ,c(0.0f, 0.0f, 1.0f);
D3DXMatrixLookAtLH(&matView, &a, &b, &c);

Note that I ignored your "without additional lines of code?" requirement, because that's a stupid requirement.

Benjamin Lindley
  • 101,917
  • 9
  • 204
  • 274