Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Non-trivial example of undefined behavior with const_cast

The following code is, as far as I understand it, undefined behavior according to the c++ standard (section 7.1.5.1.4 [dcl.type.cv]/4 in particular).

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

However, this prints '8' with every compiler and optimization setting I have tried.

Question: Is there an example that will exhibit unexpected results with this type of "implicit const_cast"?

I am hoping for something as spectacular as the results of

#include <iostream>
int main() {
    for (int i = 0; i <=4; ++i)
        std::cout << i * 1000000000 << std::endl;
}

on, e.g., gcc 4.8.5 with -O2

EDIT: the relevant section from the standard

7.1.5.1.4: 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.

In reply to the comment suggesting a duplicate; it is not a duplicate because I am asking for an example where "unexpected" results occur.

like image 930
JRG Avatar asked Jun 08 '16 16:06

JRG


1 Answers

Not as spectacular:

f.h (guards omitted):

struct F;
extern F* g;

struct F {
    F() : val(5)
    {
        g = this;
    }
    int val;
};

extern const F f;
void h();

TU1:

#include "f.h"
// definitions
F* g;
const F f;
void h() {}    

TU2:

#include "f.h"
#include <iostream>
int main() {
    h(); // ensure that globals have been initialized
    int val = f.val;
    g->val = 8;
    std::cout << (f.val == val) << '\n';
}

Prints 1 when compiled with g++ -O2, and 0 when compiled with -O0.

like image 112
T.C. Avatar answered Sep 19 '22 05:09

T.C.