改变一个const指针的值 [英] Changing the value of a const pointer

查看:120
本文介绍了改变一个const指针的值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有下面这段code的:


无效TestFunc(常量无效* const的VAR1,常量浮动VAR2)
{
  *(*浮动)VAR1 = VAR2;
}

它看起来像我改变常量的值对象的常量指针指向(感谢锐齿),它不应该被允许。事实是,我没有尝试过的编译器发出警告。这怎么可能?


解决方案

正如其他人所提到的,投移除目标的常量性至于前pression关注。当您使用投编译器根据投对待前pression - 只要投它本身有效(和C风格的转换是pretty许多大铁锤)。这就是为什么你没有得到一个错误或警告。你基本上告诉编译器,安静,我知道我在做什么,这是你应该如何对待的事情。事实上,强制转换可能是#1的方式为程序员,让编译器停止发出警告。

您分配前pression可能会或可能不会是未定义的行为。它允许抛弃常量性如果的对象实际上指向的是不是常量。

不过,如果指向的对象是常量,那么你就具有不确定的行为。

 无效TestFunc(常量无效* const的VAR1,常量浮动VAR2)
{
  *(*浮动)VAR1 = VAR2;
}
INT
主要(无效)
{
    浮X = 1.0;
    常量浮Y = 2.0;    TestFunc(安培; X,-1.0); //定义良好的(如果不是特别大的风格)
    TestFunc(安培; Y,-2.0); //未定义行为    返回0;
}

您在践踏危险水域...

在一般(我敢肯定,也有例外),铸造使前pressions治疗的对象,因为他们真的是被支持,在C / C ++良好定义的行为。

这特殊的行为进行了标准覆盖主要由声明,通过删除const修饰铸造(或其它)修改const对象是不确定的。推论是,做同样的非const对象不是不确定的。在C ++标准中给出一个例子说明了这一点。

C90 6.5.3 - 类型限定符(C99 6.7.3):


  

如果试图修改与通过使用常量限定类型定义的对象
  与非const限定类型的左值的,行为是不确定的。


C ++ 7.1.5.1对CV-预选赛


  

一个指针或引用的cv-限定的类型实际上并不需要点或引用CV-限定的对象,但如果这样做,将被视为;一个常量限定访问路径不能被用来修改即使引用的对象是一种非const对象,并且可以通过一些其它的访问路径被修改的对象。 [注:CV-预选赛是
  由类型系统支持,使它们不能在没有铸造(5.2.11)破坏。 ]


  
  

除任何类成员声明可变(7.1.1)可以修改,任何试图修改一个const
  在其一生中的对象(3.8)结果不确定的行为。


  
  

...


  
  

【例:


  
  

...

  INT I = 2; //不是CV-合格
const int的* CIP; //指向const int的
我; CIP =放大器// OK:CV-合格的访问路径不合格
* CIP = 4; //非法的构造:试图通过PTR修改为const为int *的IP;
IP = const_cast会< INT *>(CIP); //投需要转换const int的*为int *
*的ip = 4; //定义:* IP指向我,非const对象const int的* CIQ =新const int的(3); //根据需要初始化
为int *智商= const_cast会< INT *>(CIQ); //需要投
*智商= 4; //未定义:修改const对象


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?

解决方案

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.

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;
}

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):

If an attempt is made to modify an object defined with a const-qualified type through use of an lvalue with non-const-qualified type, the behavior is undefined.

C++ 7.1.5.1 The cv-qualifiers

A pointer or reference to a cv-qualified type need not actually point or refer to a cv-qualified object, but it is treated as if it does; a const-qualified access path cannot be used to modify an object even if the object referenced is a non-const object and can be modified through some other access path. [Note: cv-qualifiers are supported by the type system so that they cannot be subverted without casting (5.2.11). ]

Except that any class member declared mutable (7.1.1) can be modified, any attempt to modify a const object during its lifetime (3.8) results in undefined behavior.

...

[Example:

...

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

这篇关于改变一个const指针的值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆