Approved way to avoid lvalue cast warnings and errors?

烂漫一生 提交于 2019-12-12 00:28:00

问题


This is related to JoGusto's answer at Casting Error: lvalue required as left operand of assignment. In the answer, he/she states:

but there is one case where it is not true: casting, then dereferencing a pointer:

*((int *) chrPtrValue) = some_integer_expression;

I think I found the answer at Joseph Mansfield answer from Why does an lvalue cast work?, where he cited the standard. But that confused me more because I can differentiate between lvalues and rvalues, but xvalues and prvalues are still new to me.

Naively, it seems to me that the rule is present for a reason, so some of the methods for circumventing it would probably be [indirectly or directly] illegal also.

I have a few questions related to the lvalue cast. The use cases includ the following. In the first case, the underlying types are different. In the second case, the qualifiers were changed.

float f;
*(static_cast<int*>(&f)) = 1;

int ptr = ...;
*(static_cast<volatile int*>(&ptr)) = NULL; 

Is it legal C and C++ circumvent the lvalue cast error using indirection then dereferencing?

If the cast only changes the qualifiers (i.e., static const or volatile) , then is it still legal in C and C++?

If its legal C and C++, then does it violate other rules, like GCC's aliasing rules?

Finally, if it does violate C or C++, or other rules, then what is the approved way to do it (perhaps a memcpy or memmove)?


回答1:


The JoGusto answer is (a) not very good, and (b) on a C question.

First, is it legal C and C++ circumvent the lvalue cast error like that (indirection then dereferencing)?

IDK what you mean by "circumvent the lvalue cast error". The code (T)x = y; is just illegal nonsense (except for the case in C++ where T is an lvalue reference, as Joseph Mansfield's answer covers). You don't circumvent it; you write code that has a sensible meaning and does what you want to do.

The code *(T *)ptr = y; compiles. It means to invoke the assignment operator on a T object which is stored at the address in ptr. It's the same as (T &)*ptr = y; in C++, which is reinterpret_cast<T&>(*ptr) = y; .

does it violate other rules, like GCC's anti-aliasing rules?

The behaviour is subject to alignment and strict aliasing. If there is not actually a T object stored at that address, nor an object of type compatible with T according to the list in the strict aliasing rule (in this case: int or unsigned int), then it is undefined behaviour.

then what is the approved way to do it (perhaps a memcpy or memmove)?

You could write:

int x = some_integer_expression;
memcpy(chrPtrValue, &x, sizeof x);

I can usually differentiate between lvalues and rvalues, and not xvalues and prvalues.

Which expressions are you having trouble identifying in this example?



来源:https://stackoverflow.com/questions/31768707/approved-way-to-avoid-lvalue-cast-warnings-and-errors

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!