Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Create C++ integer class to act absolutely identical to integral integer type

Small and pretty nasty problem I've seen several days ago, asked to my friend on interview.

The initial interview question was: "What will be the output of the following code?"

int i = 2;
i = i++ + i++;

The correct answer is ((2 + 2) + 1) + 1 = 6, i.e. post-increment is applied twice before assignment, but after addition.

Then I wanted to create a simple class carrying one integer and overload operator+() and operator++(int) to see in logs the exact order, in which operators will be executed.

This is what I got:

class A
{
public:
A(int _data) : data(_data) { }

A &operator=(const A& _rhs)
{
    data = _rhs.data;
    cout<<" -- assign: "<<data<<endl;
}

A operator++(int _unused)
{
    A _tmp = data;
    data++;

    cout<<" -- post-increment: "<<data<<endl;
    return _tmp;
}

A operator+(const A &_rhs)
{
    A _tmp = data + _rhs.data;

    cout<<" -- addition: "<<data<<"+"<<_rhs.data<<endl;
    return _tmp;
}

inline operator int() const { return data; }

private:
    int data;
};

The result was pretty discouraging:

-- post-increment: 3
-- post-increment: 4
-- addition: 3+2
-- assign: 5

For less sophisticated constructions, such as (A _dt2 = a++; ), it acts as it should, but the order of operators execution is not as for integral types.

It might be compiler specific problem, I guess:

$ gcc --version
gcc (Ubuntu 4.4.3-4ubuntu5) 4.4.3
Copyright (C) 2009 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

So, I'm a bit lost :)

like image 266
user1016299 Avatar asked Oct 27 '11 11:10

user1016299


2 Answers

The initial interview question was: "What will be the output of the following code?"

int i = 2;
i = i++ + i++;

The correct answer is undefined behaviour, because you're modifying the same variable multiple times without a sequence point in between.

C++03 Standard §5 [expr] p4:

Except where noted, the order of evaluation of operands of individual operators and subexpressions of individual expressions, and the order in which side effects take place, is unspecified.

This may not answer your real question, but it will be similar even if you make an integer-like class and overload the operator++(int) and operator+(A const&). The order of evaluation of arguments to a function is unspecified, it may be done in any order the compiler likes, thus the result is unspecified.

like image 170
Xeo Avatar answered Oct 23 '22 15:10

Xeo


Aside from what others already pointed out: Taking the title of your question in isolation - "Create C++ integer class to act absolutely identical to integral integer type" - I should point out a completely different reason why it is impossible.

It is (to my knowledge) not possible to emulate the shortcut behaviour of the || and && operators with classes, i.e. both sides of the operand will be evaluated no matter what.

Edit: Check out the comments. "To my knowledge" appears to not have been enough. However, Steve Jessop has a different example that makes the overall point stand valid.

This is completely unrelated to your increment question, but topical to your question title, so I thought it should be mentioned.

like image 7
DevSolar Avatar answered Oct 23 '22 14:10

DevSolar