Ferenc Deak
Ferenc Deak

Reputation: 35408

Const behavior in operator >>

Let's consider the following code (live at: http://ideone.com/3Ky4Kr)

#include <iostream>
#include <string>
#include <cstdlib>
#include <cstring>

class StrStrTest {
public:
    StrStrTest(const std::string& ba) {
        a = (char*)calloc(1, ba.length() + 1);
        strcpy(a, ba.c_str());
    }
    virtual ~StrStrTest() {
        free(a);
    }
private:
    char* a;
    friend std::basic_ostream<char>& operator << (std::basic_ostream<char>& ss, const StrStrTest& a);
    friend std::basic_istream<char>& operator >> (std::basic_istream<char>& ss,const StrStrTest& a);
};
std::basic_ostream<char>& operator << (std::basic_ostream<char>& ss, const StrStrTest& a) {
    ss << a.a;
    return ss;
}
std::basic_istream<char>& operator >> (std::basic_istream<char>& ss,
                                       const StrStrTest& a) {
    ss >> a.a;  // <<-- HERE
//    a.a = NULL;
    return ss;
}
int main()
{
    StrStrTest bb("foo");
    std::cin >> bb;
    std::cout << bb;
}

Firstly, why does it compile? On the line marked with <<-- HERE I (subtly) modify a const object. (obviously a.a = NULL; does not compile, that's too obvious).

Secondly does this lead to undefined behaviour?

PS: Please don't consider that the code is not safe, might overwrite memory it does not own, char* vs. std::string, etc... I know these, and it is not the point of the question, this is not production code.

Upvotes: 1

Views: 68

Answers (1)

Benjamin Lindley
Benjamin Lindley

Reputation: 103713

The overload you are using is this: operator>>(std::istream&, char*). It takes a char*, by value. It doesn't modify the pointer (i.e. It doesn't change the pointer to point somewhere else). It modifies the data which the pointer holds the address of, writing a null terminated c-string to that location. So, the const-ness of your object is not being violated, because that data is not part of your object.

If you try to do something like this:

a.a = NULL;

That is modifying a member of your object, and so is not allowed.

Secondly does this lead to undefined behaviour?

It can, if a.a does not point to properly allocated memory with enough space for the next space delimited char data in the stream. But not as a result of anything to do with the const-ness of the StrStrTest object.

Upvotes: 4

Related Questions