c++

clang behaves differently than msvc++ and gcc


This code behaves surprising on Clang. Is there a bug in Clang, or are gcc and MSVC++ wrong? Or is the behaviour undefined?:

typedef set<int> A;
typedef map<int,A> B;
B gcctest;
A def;

A const& get(int key)
{
    B::const_iterator j = gcctest.find(key);
    if (j != gcctest.end())
        return j->second;
    return def;
}

int main()
{
    def.insert(1);
    int t = 47;
    gcctest[t] = get(t);
    cerr << (gcctest[t].size() ? "gcc or msvc++" : "clang") << endl;
}

It seems Clang inserts a default constructed element in my map before calling get. This does not happen if A is a simple type, e.g. int.

on GCC and MSVC++++ it prints gcc or msvc++. On clang in prints clang.

GCC on linux version 4.6.3

Clang on MacOS Xcode 5.0.2

MSVC++ on Windows VS2012

(PS: please help me with a better title for this question.)


Solution

  • When you use the subscript operator on a std::map<K, T> it finds the element and, if the element is not present, inserts one. Thus, depending on whether the left-hand side or the right-hand side of

    gcctest[t] = get(t);
    

    is evaluated first, you'll get different results. The result of the program is, however, just unspecified.