被批准的避免左值强制转换警告和错误的方法
Approved way to avoid lvalue cast warnings and errors?
这与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
const
或volatile
),那么它在C和c++中仍然合法吗?
如果它是合法的C和c++,那么它是否违反了其他规则,比如GCC的混叠规则?
最后,如果它确实违反了C或c++,或其他规则,那么批准的方法是什么(可能是memcpy
或memmove
)?
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
类型兼容的对象(在本例中为int
或unsigned int
),则为未定义行为。
那么被批准的方法是什么(可能是memcpy或memmove)?
你可以写:
int x = some_integer_expression;
memcpy(chrPtrValue, &x, sizeof x);
我通常可以区分左值和右值,而不能区分左值和右值。
在这个例子中,你在识别哪些表达方面有困难?
byacc的旧版本——可能直到1996年——实际上鼓励使用这种技术。如果我没记错的话,pcom中的代码和几个基于pcc2的编译器一样广泛地使用了该技术。(这是我的亲身经历)
- 将无符号转换为复杂<int>原因符号转换警告
- 为什么在 c++ 中索引字符串会发出隐式转换警告?
- C++:禁用隐式转换警告
- 意外 (IMO) 常量转换警告
- C++:禁用 CMake 中的旧样式转换警告
- 键入从 DWORD 到 64 位指针的强制转换警告
- 隐式转换警告 int 到 int-looklike
- 移植到 64 位时如何避免size_t int 强制转换警告?
- 构造函数中的 C4267 转换警告 - 无法修复过载?
- 如何修复隐式转换警告?
- 为什么在一种情况下,我会收到带有字符串文字的已弃用转换警告,而在另一种情况下却没有?
- 在 C++ 中修复类型转换警告的最佳方法
- 为什么仅在列表初始化的情况下才会出现狭窄的转换警告
- -在无符号字符上使用运算符 <<= 时的转换警告
- 如何在gcc或clang中启用从int到int64_t的转换警告
- 如何禁用缩小转换警告
- 使用复合赋值运算符解决转换警告
- gcc 奇怪的转换警告(<B>从"int"转换为"A::count_type {aka short unsigned int}"可能会改变其值)
- 强制缩小转换警告
- 旧风格使用sys/select.h宏强制转换警告