我有以下代码:
void TestFunc(const void * const Var1, const float Var2)
{
*(float*)Var1 = Var2;
}
看起来我正在改变const指针所指向的const对象的值(感谢sharptooth),这是不允许的.事实是,我试过的编译器都没有发出警告.这怎么可能?
Mic*_*urr 11
正如其他人所提到的,就表达式而言,强制转换会删除目标的"常量".当你使用强制转换时,编译器会根据强制转换处理表达式 - 只要强制转换本身有效(并且C样式强制转换几乎是大锤子).这就是您没有收到错误或警告的原因.你基本上是在告诉编译器,"保持安静,我知道我在做什么,这就是你应该如何对待事物".事实上,强制转换可能是程序员让编译器停止发出警告的第一种方式.
您的赋值表达式可能是也可能不是未定义的行为.如果实际指向的对象不是const ,则允许抛弃constness.
但是,如果指向的对象是const,那么您有未定义的行为.
void TestFunc(const void * const Var1, const float Var2)
{
*(float*)Var1 = Var2;
}
int
main(void)
{
float x = 1.0;
const float y = 2.0;
TestFunc( &x, -1.0); // well defined (if not particularly great style)
TestFunc( &y, -2.0); // undefined behavior
return 0;
}
Run Code Online (Sandbox Code Playgroud)
你正在踩着危险的水域......
一般情况下(我确定有例外),强制转换,以便表达式处理对象,因为它们实际上是受支持的,在C/C++中是明确定义的行为.
标准中涵盖了这种特殊行为,主要是通过删除const限定符的强制转换器(或其他东西)来修改const对象的语句是未定义的.推断是对非const对象执行相同操作并非未定义.C++标准中给出的一个例子清楚地说明了这一点.
C90 6.5.3 - 类型限定符(C99 6.7.3):
如果尝试通过使用具有非const限定类型的左值来修改使用const限定类型定义的对象,则行为是未定义的.
C++ 7.1.5.1 cv限定符
对cv限定类型的指针或引用不需要实际指向或引用cv限定对象,但它被视为具有; 即使引用的对象是非const对象并且可以通过某些其他访问路径进行修改,也不能使用const限定的访问路径来修改对象.[注意:类型系统支持cv-qualifiers,因此在不进行强制转换的情况下不能破坏它们(5.2.11).]
除了可以修改声明为mutable(7.1.1)的任何类成员之外,任何在其生命周期内修改const对象的尝试(3.8)都会导致未定义的行为.
...
[例:
...
Run Code Online (Sandbox Code Playgroud)int i = 2; //not cv-qualified const int* cip; //pointer to const int cip = &i; //OK: cv-qualified access path to unqualified *cip = 4; //ill-formed: attempt to modify through ptr to const int* ip; ip = const_cast<int*>(cip); //cast needed to convert const int*to int* *ip = 4; //defined: *ip points to i, a non-const object const int* ciq = new const int (3); //initialized as required int* iq = const_cast<int*>(ciq); //cast required *iq = 4; //undefined: modifies a const object