被批准的避免左值强制转换警告和错误的方法

Approved way to avoid lvalue cast warnings and errors?

本文关键字:转换 警告 错误 方法      更新时间:2023-10-16

这与JoGusto在cast Error的回答有关:lvalue需要作为赋值的左操作数。在回答中,他/她说:

,但有一种情况是不正确的:强制转换,然后解引用指针:

*((int *) chrPtrValue) = some_integer_expression;

我想我在Joseph Mansfield的答案中找到了答案,为什么左值转换有效?,在那里他引用了标准。但这让我更困惑,因为我可以区分左值右值,但是xvalues右值对我来说仍然是新的。

天真地说,在我看来,这个规则的存在是有原因的,所以一些规避它的方法可能也[间接或直接]是非法的。

我有几个关于左值强制转换的问题。用例包括以下内容。在第一种情况下,底层类型是不同的。在第二种情况下,修饰符被更改了。

float f;
*(static_cast<int*>(&f)) = 1;
int ptr = ...;
*(static_cast<volatile int*>(&ptr)) = NULL; 
C和c++使用间接解引用来规避左值强制转换错误是否合法?

如果强制转换只改变限定符(即static constvolatile),那么它在C和c++中仍然合法吗?

如果它是合法的C和c++,那么它是否违反了其他规则,比如GCC的混叠规则?

最后,如果它确实违反了C或c++,或其他规则,那么批准的方法是什么(可能是memcpymemmove)?

JoGusto的答案是(a)不太好,(b)在C问题上。

首先,C和c++规避左值强制转换错误(间接然后解引用)是否合法?

不知道你所说的"规避左值强制转换错误"是什么意思。代码(T)x = y;只是非法的废话(除了c++中T是左值引用的情况,正如Joseph Mansfield的回答所涵盖的那样)。你不能规避它;你写的代码有一个合理的意义,做你想做的。

*(T *)ptr = y;编译的代码。它意味着对T对象调用赋值操作符,该对象存储在ptr中的地址。它与c++中的(T &)*ptr = y;相同,即reinterpret_cast<T&>(*ptr) = y;

是否违反了其他规则,比如GCC的反混叠规则?

行为受制于对齐和严格混叠。如果在该地址中没有实际的T对象,也没有根据严格混叠规则中的列表与T类型兼容的对象(在本例中为intunsigned int),则为未定义行为。

那么被批准的方法是什么(可能是memcpy或memmove)?

你可以写:

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

我通常可以区分左值和右值,而不能区分左值和右值。

在这个例子中,你在识别哪些表达方面有困难?

byacc的旧版本——可能直到1996年——实际上鼓励使用这种技术。如果我没记错的话,pcom中的代码和几个基于pcc2的编译器一样广泛地使用了该技术。(这是我的亲身经历)