6

I was looking through the interview questions to a junior C++ developer position. The question is (quote):

Is the following code correct?

struct Foo
{
    int i;
    void foo ( void ) const
    {
        Foo* pointer = const_cast<Foo*>(this);
        pointer->i = 0;
    }
};

I would answer:

The code itself is valid according to the C++03 and c++11 standards and will compile successfully. But it may invoke an undefined behavior during assignment pointer->i = 0; if the instance of the class on which foo() is being called is declared as const.

I mean that following code will compile successfully and result in undefined behaviour.

struct Foo
{
    int i;
    Foo ( void )
    {

    }
    void foo ( void ) const
    {
        Foo* pointer = const_cast<Foo*>(this);
        pointer->i = 0;
    }
};

int main ( void )
{
    Foo foo1;
    foo1.foo();   // Ok

    const Foo foo2;
    foo2.foo();   // UB

    return 0;
}

Is my answer correct or I am missing something? Thank you.

Kolyunya
  • 5,973
  • 7
  • 46
  • 81

3 Answers3

5

I would first ask what is meant by their ambiguous definition of "correct". You need to know the specification of the program and its intended behaviour.

As you said, if they're just asking if it compiles then the answer is 'yes'. However, if they determine correct to be safe to do, then you can discuss the facts that you state in your question.

By answering this way, the person interviewing can see how that you're analysing what you're being asked, rather than jumping straight into answering, which in my opinion is a good thing to do.

TheDarkKnight
  • 27,181
  • 6
  • 55
  • 85
1

This code may be legally correct, but I guess, the aim of the question is to determine, whether you understood the concept of const itself. Because, on the semantic level, you have a function taking an implicit const object pointer, which it then goes to modify, which is almost certainly a bug.

There are cases, where this may be desired (because the modification is some caching of return values, or similar operation that does not change the semantic value of the object), you would use the mutable keyword for the variable in question.

cmaster - reinstate monica
  • 38,891
  • 9
  • 62
  • 106
  • Thank you. This is nice idea to mention in the answer that declaring `i` as `mutable` will fix the mentioned possible UB. – Kolyunya Jul 24 '13 at 12:21
  • Removing *constness* is a sign of bug in design. Then, you start to analyze the consequences of this. – SChepurin Jul 24 '13 at 12:48
0

cheating complier will take the consequences.

struct Foo
{
    int i;

    Foo(int a):i(a){}

    void foo ( void ) const
    {
        Foo* pointer = const_cast<Foo*>(this);
        pointer->i = 0;
    }

    bool operator<(const Foo& rhs) const{
        return i<rhs.i;
    }
};

#include <map>

int main ( void )
{
    std::map<Foo,int> kk;

    for(int i=0;i<10;++i){
        kk.insert(std::make_pair(Foo(i),i));
    }

    std::map<Foo,int>::iterator ite = kk.find(Foo(4));
    const Foo& foo4 = ite->first;
    foo4.foo();

    ite = kk.find(Foo(4));
    const Foo& tmp = ite->first; // crack

    return 0;
}

program will crack at "const Foo& tmp = ite->first;"

thomas
  • 505
  • 3
  • 12