While compiling (with Linux Server release 6.1)
strftime(AppTime, sizeof(AppTime),"%Y/%m/%d %T", localtime(&((long)u32_Time)));
getting error "error: lvalue required as unary '&' operand"
but the same code compiled successfully with Red Hat Enterprise Linux AS release 3.
Why so? How to correct this?
This error occurs when we put constants on left hand side of = operator and variables on right hand side of it. Example: #include <stdio.h>
lvalue means an assignable value (variable), and in assignment the left value to the = has to be lvalue (pretty clear). Both function results and constants are not assignable ( rvalue s), so they are rvalue s.
The address-operator &
requires a variable to take the address from. The result of your cast (long)u32_Time
is a temporary that does not necessarily reside in memory and therefore has no address that could be taken. So if that piece of code ever compiled somewhere it was a nonstandard compiler extension.
The standard, §5.3.1,3 demands:
The result of the unary & operator is a pointer to its operand. The operand shall be an lvalue [...]
How to fix this:
std::localtime
expects a pointer to a std::time_t
so you best provide that. You did not provide any explanation or further code, so I can only guess that u32_Time
is some 4 byte unsigned arithmetic type that is supposed to represent a time in some manner. How that is properly converted into a std::time_t
depends on how your compiler implements the latter and how you got the value of the further. Simply applying a C-cast is not portable, and casting to long
is even less portable.
If, and only if the std::time_t
on your current platform is also a unsigned 32 bit type using the same representation as your u32_Time
, it might suffice to use
localtime(reinterpret_cast<std::time_t*>(&u32_Time));
More portable would be storing the value in the correct data type first:
std::time_t time = u32_Time;
localtime(&time);
That way you will get the necessary warnings and/or errors if time_t
and the type of u32_Time
are not compatible.
I would strongly advice against using C-casts, because once you have to port this piece of code to another platform you will have no means to find that nasty cast easily.
It's probably best to start with what the error means. An "lvalue" is something that appears on the left side of an equals sign. What it means is that your argument to the "address of" operator (&) must be something that you could assign to. In your case, this isn't syntactically correct:
(long)u32_Time = 0;
The reason for this restriction is that the & operator returns the address of something that is stored somewhere. (long)u32_Time isn't stored somewhere, but u32_Time is.
This might have worked ok on more tolerant compilers because it would allocate some space for the long representation of u32_Time and then give you a pointer to that, but I wouldn't count on that working (as can be seen in Linux Server release 6.1).
To fix this, you can just create a new variable and take it's address instead:
long long_Time = (long)u32_Time;
strftime(AppTime, sizeof(AppTime),"%Y/%m/%d %T", localtime(&long_Time));
However, that's still not perfect. localtime expects a time_t pointer, not a long pointer, and while they might be the same on your platform, you'd be better off with:
time_t time_t_Time = (time_t)u32_Time;
strftime(AppTime, sizeof(AppTime),"%Y/%m/%d %T", localtime(&time_t_Time));
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With