How to get the address of the return value of a function in C ++

Given this prototype that Endian converts:

time_t Flip( time_t );

      

I would like to use the return value in a function that takes BYTE * as an argument. Something like that:

SetBytesAt( 0, (BYTE*)&(Flip( t )) );

      

But that doesn't compile. Gives me this error "& requires l-value". If () is removed from the Flip function, the same error is generated.

Now I know I can just do this:

time_t temp_t = Flip( t );
SetBytesAt( 0, (BYTE*)&temp_t );

      

But it seems to me that I have to accomplish the same thing without the temp_t temporary variable.

+3


source to share


7 replies


Unfortunately no. You cannot take the address of the temporary (more correctly, r-value ). This is exactly how the language was defined.



+8


source


Don't try this at home.

template <typename T>
class AddressableTemporary
{
public:

    AddressableTemporary(T const value)
        : value_(value)
    {
    }

    operator T*() { return &value_; }

private:

    T value_;
};

template <typename T>
AddressableTemporary<T> MakeAddressable(T value)
{
    return AddressableTemporary<T>(value);
}

      

Used like:



int  F() { return 42; }
void G(int const* const p) { std::cout << *p; }

int main()
{
    G(MakeAddressable(F()));
}

      

But really, don't do it. Either use a variable, or write a wrapper function that encapsulates the use of a variable, or rework your code so you don't have to worry about it (for example, change the function to accept, say, a constant reference).

+3


source


You need to use a temporary variable. You can only accept the address of l-values. Unable to accept return address.

On some platforms, the return value is only stored in a register and therefore does not even have an address. You need to store it in memory before you can pass its address to another function.

0


source


As far as I know, this is not possible in C ++.

Ask yourself: How do you access the changed result after returning SetBytesAt

?

The return values ​​are usually copied (or moved) to the actual variable in the caller function. The temporary space reserved for the return value is no longer available after the function returns. In theory, you would become a stack that is no longer valid. This error occurs in practice when returning references to local variables.

0


source


You cannot pinpoint the exact reason given in the error message - & requires l-value

.

The call is Flip(t)

not an l-value, so this is not possible.

0


source


Actually, this became possible in C ++ 11. There r-value references were introduced. However, I don't know which compiler is already doing this.

0


source


You don't have to do what you want to do, but it is not clean.

Here:

template< class Type >
Type const& ref( Type const& v ) { return v; }

int main()
{
    time_t t = blah blah;
    SetBytesAt( 0, const_cast<Byte*>( reinterpret_cast<Byte const*>( &ref( Flip( t ) ) ) ) );
}

      

Technically this might work if it is SetBytesAt

copying bytes, but if it SetBytesAt

stores a pointer and that pointer is later used, then this behavior is undefined.

In any case, don't do it.

Now I have listed what is wrong with the original concept:

  • Discarding type knowledge with an unsigned pointer argument.
    β†’ Means a lot of extra work because the type is unknown.

  • Discarding const knowledge with a pointer to a non-const argument.
    β†’ Means a lot of extra work because the unknown is unknown.

  • Reverse data byte order = ungood, excluding low-level network code.
    β†’ Means a lot of extra work because the byte order is unknown.

So, don't do this.

Instead, do the opposite: store the type information, store the constant information, and don't be confused with raw bytes.

0


source







All Articles