sebbot

Contrary to what you might expect, this simple code fails to compile under
Visual C++ 8:

#include <stdexcept>
#include <string>

namespace {
class TestClass
{
TestClass(const std::string& str) {}
TestClass(const std::exception& ex) {}
};
}

int main()
{
TestClass testClass("test");
}

The compiler bails out saying:

c:\build\test\source1.cpp(14) : error C2668: '`anonymous-namespace'::TestClass::TestClass' : ambiguous call to overloaded function
c:\build\test\source1.cpp(8): could be '`anonymous-namespace'::TestClass::TestClass(const std::exception &)'
c:\build\test\source1.cpp(7): or '`anonymous-namespace'::TestClass::TestClass(const std::string &)'
while trying to match the argument list '(const char [5])'

The problem is, that std::exception has, for unknown reasons, a non-explicit
constructor from const char*. However, the C++ standard does not specify
any other constructor than the default one for std::exception (see
http://www.open-std.org/jtc1/sc22/open/n2356/lib-support.html#lib.exception).

My questions are:

  1. Why doesn't Microsoft make this constructor explicit in order to prevent this unexpected conversion
  2. Is there any way to disable this feature, which is, in fact, a bug


Re: Visual C++ General disabling implicit conversion from const char* to std::exception

einaros

 sebbot wrote:


  1. Why doesn't Microsoft make this constructor explicit in order to prevent this unexpected conversion
  2. Is there any way to disable this feature, which is, in fact, a bug

It's no more of a bug than

class Foo
{
public:
    Foo(const char*) {}
};

class Bar
{
public:
    Bar(const char*) {}
};

class MyClass
{
public:
    MyClass(const Foo&) {}
    MyClass(const Bar&) {}
};

MyClass m("hello world");

There's nothing specifying that char* -> std::string is a better conversion than char* -> std::exception, so you'll just have to be more precise about what you feed the function.






Re: Visual C++ General disabling implicit conversion from const char* to std::exception

sebbot

Nevertheless, doing something like
throw std::exception("string");
is not supported according to the C++ standard. So why wasn't this constructor made explicit

 einaros wrote:

There's nothing specifying that char* -> std::string is a better conversion than char* -> std::exception


Automatic conversion from char* to std::string
is better than std::exception, as std::string is very similar to char* in functionality and purpose.
std::exception however is not, so I don't see why one shouldn't make it explicit.





Re: Visual C++ General disabling implicit conversion from const char* to std::exception

einaros

 sebbot wrote:
Nevertheless, doing something like
throw std::exception("string");
is not supported according to the C++ standard. So why wasn't this constructor made explicit

Since std::exception has a ctor which accepts const c-strings, it wouldn't do you any good to add the explicit modifier.


 sebbot wrote:

Automatic conversion from char* to std::string
is better than std::exception, as std::string is very similar to char* in functionality and purpose.
std::exception however is not, so I don't see why one shouldn't make it explicit.

While it may *suit* you better, it *isn't* better. c-strings are c-strings, stl strings are stl strings. The standard doesn't make any distinction for such for overload resolution.






Re: Visual C++ General disabling implicit conversion from const char* to std::exception

sebbot

einaros wrote:


Since std::exception has a ctor which accepts const c-strings, it wouldn't do you any god to add the explicit modifier.



It would, as the compiler would no longer see ambiguity errors when compiling the piece
of code mentioned in the first post.

Also, I've checked several implementations of the C++ standard library (GNU libstdc++, STLport, libcomo (C++ Standard Library implementation of Comeau Computing), Rouge Wave, Dinkumware,
stdcxx (Apache C++ Standard Library implementation), Recursion Software's STL implementation)
and none of them implements this specific constructor.
Now, I've got nothing to say against that constructor, only that it's not explicit. This is a problem
as it causes unexpected behavior when trying to design platform independent code.

Whereas the code mentioned in the first post works in most environments, Visual C++ requires me to write
TestClass testClass(std::string("test"));




Re: Visual C++ General disabling implicit conversion from const char* to std::exception

einaros

For some reason I was of the impression that you were talking of changing *your* TestClass ctors to be explicit. Re-reading the text I see what you're getting at. The fact that the std::exception implementation is different in the MS libs from e.g. Dinkumware hadn't caught my eye yet, but now that you mention it, I seem to recall there being some dispute either here or on the language forum about the explicit'ness of some of the other STL constructors.

In either case, report it at http://connect.microsoft.com/VisualStudio, and let MS decide what to do with it.






Re: Visual C++ General disabling implicit conversion from const char* to std::exception

sebbot

einaros wrote:

In either case, report it at http://connect.microsoft.com/VisualStudio, and let MS decide what to do with it.

I've just discovered that there's already a bug report for this problem (https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx FeedbackID=200471)
which is to be fixed in "an upcoming release of Visual Studio", whatever that means exactly...




Re: Visual C++ General disabling implicit conversion from const char* to std::exception

einaros

sebbot wrote:

I've just discovered that there's already a bug report for this problem (https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx FeedbackID=200471)
which is to be fixed in "an upcoming release of Visual Studio", whatever that means exactly...

That means Visual Studio Orcas. Seeing as it's already on their radar, it'll be fixed sooner.