There are different value types in C++ types. To take the address of something with &, it needs to be an l-value. Temporary variables, like what enviroment->getDirectionalLight()->getAmbientIntensity() returns, are r-values, which means you can't take their address.

Think of it like this: Where does the float returned by enviroment->getDirectionalLight()->getAmbientIntensity() live? Where is its home? Answer: it doesn't have one. It's "homeless." It's just a temporary float that's being returned by a function, and so it never gets a "home" assigned to it. If something doesn't have a home, how can you take its address? You can't. The address points to "home," and thus if you could take its address it would have a home in the first place!

Why is this important? Well, look at that function. It's taking a pointer to a float. That means the function has the power and ability to change that float. But that float is temporarily existing. You can't change a temporary like that. If you could do that, then why not be able to do int* x = &2; *x = 3; (uh oh... did we just change 2 to now be 3? that's (one reason) why something like this isn't legal).

Note that this is a pretty high level explanation. You could get super technical and say that the temporary float does (or even better: might) have a home, but I don't really want to get into those details too much. If you want to view it like this, just think of it as a super temporary home that has some special rules you can't mess with. Kind of like a guest-home. The float is just a guest at the home, it doesn't "own" the home. You can't go in and start changing things in a home you don't own. Not legally, at least.

Another question is why does the function take a pointer? If it were returning a value, it could easily just return a float value, unless it is expected to read and write this value over time; in the latter case, passing the return value of that function is immediately a bad idea. This strikes me as a function that takes an array of float values, so even if you assigned the temporary to a variable, then sent its address, that'd be trouble.

He likely is trying to say that the value that is returned is expected change while he's holding the pointer to it, and he wants to always have the updated value without having to get it again each time.

Then this will be a problem; technically, the temporary value might be in memory, or it might not be in memory at all. Even if it is, it's address will likely be different each time it is called. You'll have to find a way around it.

I would suggest getting a pointer to the data that the function returns (might not be a good idea, because it has an interface in place to get it, so handling it yourself might defy assumptions that the code makes), or holding on to the data in some sort of cache like Cornstalks mentioned, and having some sort of system to know when it is time to update it.

The problem with watching for an update is that now a large section of my code needs to be hard coded to refresh values.

Where as if I can store pointers to the piece of data I will will not have to hard code that side of things.

No, you just have an even-worse slew of new problems to handle, such as life-times of the pointers.
Even if you went with your pointer system you would still have to “hard-code” the telling to the shader that the pointer is no longer valid.

I don’t believe you are using the word “hard-code” correctly either.
What does that mean and how does it relate to a system such as this?
When some things change, sometimes other systems or objects need to be notified and updated. This isn’t hard-coding. It’s just…coding.

Besides that, you are trying to escape a simple update-when-changed system for a pointer-based system which means your intention is to set the pointer once and leave it.
That means you have no intention of using the same shader between multiple objects as that would require re-updating the pointer for each object (which would make the pointer system pointless since that many re-updates would mean that the shader would always have the most up-to-date value in it anyway).
The point is you can’t share your shaders and this is a major loss in both resources and performance.

Basically, your overall design needs to be re-evaluated, and your real underlying issue isn’t as simple as floats and pointers. To solve this issue you must look beyond the beyond, young Kimosabe. You must acknowledge that “grey” does not have an “a” in it, and you can’t ignore the chocolate cake any longer. The time has come…

A good start would be to explain what you mean by “hard-coded” and what exactly is so wrong with your current system that you feel the need to make an even-worse system.

In my country's variant of English, its preferred spelling is "gray", with "grey" as an accepted alternative.

Also, I agree with figuring out exactly what you need and establishing why you need it, rather than making several drawn out patches to a system that likely wasn't what you had in mind when you started.

There are different value types in C++ types. To take the address of something with &, it needs to be an l-value. Temporary variables, like what enviroment->getDirectionalLight()->getAmbientIntensity() returns, are r-values, which means you can't take their address.

Think of it like this: Where does the float returned by enviroment->getDirectionalLight()->getAmbientIntensity() live? Where is its home? Answer: it doesn't have one. It's "homeless." It's just a temporary float that's being returned by a function, and so it never gets a "home" assigned to it. If something doesn't have a home, how can you take its address? You can't. The address points to "home," and thus if you could take its address it would have a home in the first place!

Why is this important? Well, look at that function. It's taking a pointer to a float. That means the function has the power and ability to change that float. But that float is temporarily existing. You can't change a temporary like that. If you could do that, then why not be able to do int* x = &2; *x = 3; (uh oh... did we just change 2 to now be 3? that's (one reason) why something like this isn't legal).

Note that this is a pretty high level explanation. You could get super technical and say that the temporary float does (or even better: might) have a home, but I don't really want to get into those details too much. If you want to view it like this, just think of it as a super temporary home that has some special rules you can't mess with. Kind of like a guest-home. The float is just a guest at the home, it doesn't "own" the home. You can't go in and start changing things in a home you don't own. Not legally, at least.

Well that is kind of true. All temporary file does have a home, because i just tried that

And i was a able to modify 12 to 22. Also when i try printing the address of 12 it does print out an Address. The interesting thing is that the return value when i print it the address is still valid. The thing that was very interesting though is that if you look at the Assembly you will notice that the value that is assign to foo is still valid in the assembly code.

That's undefined behavior right there. I don't think you can rely on undefined behavior to come to any kind of meaningful conclusions about what the standard guarantees.

And i was a able to modify 12 to 22. Also when i try printing the address of 12 it does print out an Address. The interesting thing is that the return value when i print it the address is still valid. The thing that was very interesting though is that if you look at the Assembly you will notice that the value that is assign to foo is still valid in the assembly code.

Without trying to get super technical in this thread, temporaries may or may not have addresses associated with them, as they can potentially be completely optimized away or live entirely in a register instead of in memory. But yes, as you have noticed, you can pass a temporary or literal by const reference, which implies it's got some address or memory location associated with it (this is most easily proven by simply taking and printing the address of the const reference). A situation like this would fall under the "the temporary is just a guest in a temporary home" situation I described at the end. It's also important to note that when you print out that address, it is not still valid (that is, the temporary no longer exists in any way, shape, or form (as far as the standard guarantees), so that address you're printing out is just the temporary's old address, not a currently valid address (because the temporary doesn't even exist... how can you address it?))