当前位置:  开发笔记 > 编程语言 > 正文

C/C++改变了const的值

如何解决《C/C++改变了const的值》经验,为你挑选了4个好方法。

我有一篇文章,但我失去了它.它展示并描述了一些人们应该小心的C/C++技巧.其中一个让我感兴趣,但现在我正在尝试复制它,我无法将其编译.

这个概念是可以随意改变constC/C++ 中a的值

它是这样的:

const int a = 3;          // I promise I won't change a
const int *ptr_to_a = &a; // I still promise I won't change a
int *ptr;
ptr = ptr_to_a;

(*ptr) = 5;               // I'm a liar; a is now 5

我想向朋友展示这个,但现在我错过了一步.有谁知道它开始编译和工作缺少什么?

ATM我从'const int*'到'int*'的转换无效,但是当我读到我试过的文章时,它运行得很好.



1> sfossen..:

你需要抛弃常量:

linux ~ $ cat constTest.c
#include 


void modA( int *x )
{
        *x = 7;
}


int main( void )
{

        const int a = 3; // I promisse i won't change a
        int *ptr;
        ptr = (int*)( &a );

        printf( "A=%d\n", a );
        *ptr = 5; // I'm a liar, a is now 5
        printf( "A=%d\n", a );

        *((int*)(&a)) = 6;
        printf( "A=%d\n", a );

        modA( (int*)( &a ));
        printf( "A=%d\n", a );

        return 0;
}
linux ~ $ gcc constTest.c -o constTest
linux ~ $ ./constTest
A=3
A=5
A=6
A=7
linux ~ $ g++ constTest.c -o constTest
linux ~ $ ./constTest
A=3
A=3
A=3
A=3

另外,常见的答案在g ++ 4.1.2中不起作用

linux ~ $ cat constTest2.cpp
#include 
using namespace std;
int main( void )
{
        const int a = 3; // I promisse i won't change a
        int *ptr;
        ptr = const_cast( &a );

        cout << "A=" << a << endl;
        *ptr = 5; // I'm a liar, a is now 5
        cout << "A=" << a << endl;

        return 0;
}
linux ~ $ g++ constTest2.cpp -o constTest2
linux ~ $ ./constTest2
A=3
A=3
linux ~ $

顺便说一句......这是永远不推荐的...我发现g ++不允许这种情况发生..所以这可能是你遇到的问题.


它不能可靠地工作的事实应该是一个很好的指示,说明为什么说谎对编译器是坏的.

2> Adam Rosenfi..:

只是一个猜测,但一个常见的问题是为什么一个人不能转换int**为a const int**,这看起来是合理的(毕竟,你只是添加一个const,这通常是好的).原因是如果你可以这样做,你可能会意外地修改一个const对象:

const int x = 3;
int *px;
const int **ppx = &px;  // ERROR: conversion from 'int**' to 'const int**'
*ppx = &x;  // ok, assigning 'const int*' to 'const int*'
*px = 4;    // oops, just modified a const object

这是一个非常不直观的结果,但是确保const在这种情况下无法修改对象的唯一方法(注意没有类型转换)是使第3行成为错误.

您只能const在第一级间接添加时不添加强制转换:

int * const *ppx = &px;  // this is ok
*ppx = &x;               // but now this is an error because *ppx is 'const'

在C++中,如果const不使用某种类型的类型转换,则无法修改对象.您必须使用C风格的强制转换或C++风格const_cast来删除const-ness.任何其他尝试这样做都会导致编译器错误.


我时不时地再次完成这个推理.它总是让我头疼.

3> Andrew Khosr..:

请注意,标准未定义任何抛弃constness的尝试.从标准的7.1.5.1开始:

除了可以修改任何声明为mutable的类成员之外,任何在其生命周期内修改const对象的尝试都会导致未定义的行为.

在使用此示例之后:

const int* ciq = new const int (3);     //  initialized as required
int* iq = const_cast(ciq);        //  cast required
*iq = 4;                                //  undefined: modifies a  const  object

因此,简而言之,使用标准C++是不可能的.

此外,当编译器遇到类似的声明时

const int a = 3; // I promisse i won't change a

可以自由地将任何出现的'a'替换为3(实际上做同样的事情#define a 3)



4> Paul Tomblin..:

回到时间的迷雾,我们古代程序员使用FORTRAN.FORTRAN通过引用传递了所有参数,并没有进行任何类型检查.这意味着很容易意外地改变甚至是文字常量的值.您可以将"3"传递给SUBROUTINE,然后它会更改,因此每次从那时起您的代码都有一个"3",它实际上会像一个不同的值.让我告诉你,这些都是难以找到并修复的错误.

推荐阅读
ERIK又
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有