这与 JoGusto 在 Casting Error: lvalue required as left operand of assignment 的回答有关.在回答中,他/她说:
but there is one case where it is not true: casting, then dereferencing a pointer:
*((int *) chrPtrValue) = some_integer_expression;
我想我在 Joseph Mansfield 的回答中找到了答案 Why does an lvalue cast work? ,他引用了标准。但这让我更加困惑,因为我可以区分 lvalues 和 rvalues,但是 xvalues 和 prvalues 仍然是新的我。
天真地,在我看来,该规则的存在是有原因的,因此一些规避它的方法也可能 [间接或直接] 非法。
我有几个与左值转换相关的问题。用例包括以下内容。在第一种情况下,底层类型不同。在第二种情况下,限定符发生了变化。
float f;
*(static_cast<int*>(&f)) = 1;
int ptr = ...;
*(static_cast<volatile int*>(&ptr)) = NULL;
C 和 C++ 使用间接然后取消引用来规避左值转换错误是否合法?
如果转换仅更改限定符(即 static
const
或 volatile
),那么它在 C 和 C++ 中仍然合法吗?
如果它是合法的 C 和 C++,那么它是否违反了其他规则,例如 GCC 的别名规则?
最后,如果它确实违反了 C 或 C++ 或其他规则,那么批准的方法是什么(可能是 memcpy
或 memmove
)?
最佳答案
JoGusto 的答案是 (a) 不太好,并且 (b) 在 C 问题上。
First, is it legal C and C++ circumvent the lvalue cast error like that (indirection then dereferencing)?
我知道你所说的“规避左值转换错误”是什么意思。代码(T)x = y;
只是非法的废话(C++ 中的情况除外,其中 T
是左值引用,正如 Joseph Mansfield 的回答所涵盖的那样)。你不规避它;您编写的代码具有合理的含义并且可以执行您想要执行的操作。
代码*(T *)ptr = y;
编译。这意味着在 T
上调用赋值运算符对象存储在 ptr
中的地址.与(T &)*ptr = y;
相同在 C++ 中,即 reinterpret_cast<T&>(*ptr) = y;
.
does it violate other rules, like GCC's anti-aliasing rules?
行为受制于对齐和严格的别名。如果实际上没有 T
存储在该地址的对象,也不是与 T
兼容类型的对象根据严格别名规则中的列表(在本例中为:int
或 unsigned int
),则为未定义行为。
then what is the approved way to do it (perhaps a memcpy or memmove)?
你可以这样写:
int x = some_integer_expression;
memcpy(chrPtrValue, &x, sizeof x);
I can usually differentiate between lvalues and rvalues, and not xvalues and prvalues.
在此示例中,您难以识别哪些表达式?
关于c++ - 批准的避免左值转换警告和错误的方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31768707/