根据我的理解,以下代码是根据c ++标准的未定义行为(特别是第7.1.5.1.4节[dcl.type.cv]/4).
#include <iostream>
struct F;
F* g;
struct F {
    F() : val(5)
    {
        g = this;
    }
    int val;
};
const F f;
int main() {
    g->val = 8;
    std::cout << f.val << std::endl;
}
但是,这打印'8'与我尝试过的每个编译器和优化设置.
问题:是否存在使用此类"隐式const_cast"显示意外结果的示例?
我希望有一些像结果一样壮观的东西
#include <iostream>
int main() {
    for (int i = 0; i <=4; ++i)
        std::cout << i * 1000000000 << std::endl;
}
例如,gcc 4.8.5 with -O2
编辑:标准的相关部分
7.1.5.1.4:除了可以修改声明为mutable(7.1.1)的任何类成员之外,任何在其生命周期内修改const对象的尝试(3.8)都会导致未定义的行为.
在回复提出重复的评论; 它不是重复的,因为我要求一个"意外"结果发生的例子.
我今天正在重读c ++入门(第4版) - 关于成员函数和const引用的部分等,我想出了这个奇怪的小程序:
using std::cout;
using std::endl;
class ConstCheater
{
public:
    ConstCheater(int avalue) : ccp(this), value(avalue) {}
    ConstCheater& getccp() const {return *ccp;}
    int value;
private:
    ConstCheater* ccp;
};
int main()
{
    const ConstCheater cc(7); //Initialize the value to 7
    cout << cc.value << endl;
    cc.getccp().value = 4;    //Now setting it to 4, even though it's const!
    cout << cc.value << endl;
    cc.value = 4;             //This is illegal
    return 0;
}
我的问题是 - 为什么c ++允许这样的语法?为什么我可以在类声明为const时编辑类中的普通数据成员?是不是const的POINT使它不能修改值?
假设你有一堂课
    class C 
    {
      int * i;
      public:
         C(int * v):i(v) {};
         void method() const;  //this method does not change i
         void method();        //this method changes i
    }
现在您可能想要定义此类的const实例
    const int * k = whatever;
    const C c1(k); //this will fail
但是这会因为非const int C的构造函数C(int*v)而失败
所以你定义了一个const int构造函数
    C(const int * v):i(v) {}; //this will fail also
但是这也会失败,因为C的成员"int*i"是非const的.
在这种情况下该怎么办?使用可变吗?铸件?准备const版本的课程?
编辑:经过与Pavel的讨论(下图),我对此问题进行了一些调查.对我来说,C++的作用并不正确.指针目标应该是严格类型,这意味着您不能执行以下操作:
int i;
const int * ptr;
ptr = & i;
在这种情况下,语言语法将const承诺不改变指针的目标.另外int * const ptr是承诺不改变指针值本身.因此,您有两个可以应用const的地方.那么你可能希望你的类为指针建模(为什么不).在这里,事情正在崩溃.C++语法提供了const方法,它们能够保证不会自己更改字段的值,但是没有语法指出你的方法不会改变你的类指针的目标.
解决方法是定义两个类const_C,C …
假设我有以下课程:
struct A{
  void method(A& otherA) const{
    /* Mutate otherA */
  }
};
然后我有这个:
A myA;
myA.method(myA);
我告诉编译器method不会更改this实例,但编译器是否意识到我可以将this实例作为参数传递?
这样做我可以打破这些东西吗?这是定义的行为吗?