更改 const 指针的值
我有以下代码:
void TestFunc(const void * const Var1, const float Var2) { *(float*)Var1 = Var2; }
看起来我正在更改 const 指针指向的 const 对象的值(感谢 Sharptooth),这是不允许的。 事实上,我尝试过的编译器都没有发出警告。 这怎么可能?
I have the following piece of code:
void TestFunc(const void * const Var1, const float Var2) { *(float*)Var1 = Var2; }
It looks like I am changing the value of the const object the const pointer points to (thanks sharptooth), which should not be allowed. Fact is, none of the compilers I tried issued a warning. How is this possible?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
正如其他人提到的,就表达式而言,强制转换消除了目的地的“常量”。 当您使用强制转换时,编译器会根据强制转换来处理表达式 - 只要强制转换本身有效(C 风格强制转换几乎是大锤子)。 这就是您不会收到错误或警告的原因。 你本质上是在告诉编译器,“安静,我知道我在做什么,这就是你应该如何对待事情”。 事实上,强制转换可能是程序员让编译器停止发出警告的第一种方法。
您的赋值表达式可能是也可能不是未定义的行为。 如果实际指向的对象不是 const,则允许放弃 constness。
但是,如果指向的对象是 const,那么您就会有未定义的行为。
你正在踏入危险的水域......
一般来说(我确信有例外),C/C++ 中支持强制转换,以便表达式按照对象的实际情况对待对象,且定义良好的行为。
标准中主要通过通过删除 const 限定符的强制转换(或其他内容)来修改 const 对象的语句来涵盖这种特定行为,这些语句是未定义的。 推论是,对非常量对象执行相同操作并不是未定义的。 C++ 标准中给出的示例清楚地说明了这一点。
C90 6.5.3 - 类型限定符 (C99 6.7.3):
C++ 7.1.5.1 cv 限定符
As others mentioned, the cast removes the 'constness' of the destination as far as the expression is concerned. When you use a cast the compiler treats the expression according to the cast - as long as the cast itself it valid (and C-style casts are pretty much the big hammer). This is why you don't get an error or warning. You're essentially telling the compiler, "be quiet, I know what I'm doing, this is how you should treat things". In fact, casts are probably the #1 way for programmers to get the compiler to stop issuing warnings.
Your assignment expression may or may not be undefined behavior. It is permitted to cast away constness if the object actually pointed to is not const.
However, if the object pointed to is const, then you have undefined behavior.
You're treading dangerous waters...
In general (I'm sure there are exceptions), casting so that expressions treat objects as they really are is supported, well-defined behavior in C/C++.
This particular behavior is covered in the standards mostly by statements that modifying a const object through a cast (or something) that removes the const qualifier is undefined. The inference is that doing the same for a non-const object is not undefined. An example given in the C++ standard makes this clear.
C90 6.5.3 - Type Qualifiers (C99 6.7.3):
C++ 7.1.5.1 The cv-qualifiers
您更改指针指向的对象,而不是指针值。
C 风格强制转换的作用类似于 const_cast,并从指针上删除 const 修饰符。 编译器现在没有什么可抱怨的了。
You change the object the pointer points to, not the pointer value.
C-style cast acts like a const_cast and removes the const modifier off the pointer. The compiler now has nothing to moan about.
强制转换是合法的,但行为未定义。
The cast is legal, but the behaviour is undefined.