From: Andrew on
I hope that some kind person will post chapter and verse for why it is
wrong to say:

throw std::exception("some error text");

I know it's morally wrong. I always throw a derived class myself. But
I have come across some legacy code that does this on a project I am
working on. It was drawn to my attention because I tried compiling
with gcc rather than the Microsoft Visual Studio compiler. gcc barfs,
saying that there is not suitable constructor. Quite logical IMO. The
derived classes have the ctor that's needed.

It looks like studio has a constructor that it allowing it to compile.
Or maybe its a compiler bug (there are so many). I don't know and I
don't care why studio lets it through. I need an argument for why the
legacy code should be corrected^H^H^H^H^H^H^H^H^Hchanged. A snippet
from the std would be ideal.

Regards,

Andrew Marlow

--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

From: Seungbeom Kim on
Andrew wrote:
> I hope that some kind person will post chapter and verse for why it is
> wrong to say:
>
> throw std::exception("some error text");
>
> I know it's morally wrong. I always throw a derived class myself. But
> I have come across some legacy code that does this on a project I am
> working on. It was drawn to my attention because I tried compiling
> with gcc rather than the Microsoft Visual Studio compiler. gcc barfs,
> saying that there is not suitable constructor. Quite logical IMO. The
> derived classes have the ctor that's needed.
>
> It looks like studio has a constructor that it allowing it to compile.
> Or maybe its a compiler bug (there are so many). I don't know and I
> don't care why studio lets it through. I need an argument for why the
> legacy code should be corrected^H^H^H^H^H^H^H^H^Hchanged. A snippet
> from the std would be ideal.

ISO/IEC 14882:2003
18.6.1 Class exception

namespace std {
class exception {
public:
exception() throw();
exception(const exception&) throw();
exception& operator=(const exception&) throw();
virtual �exception() throw();
virtual const char* what() const throw();
};
}

The class simply doesn't have a constructor taking a string argument.

--
Seungbeom Kim

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

From: red floyd on
On Feb 24, 2:25 pm, Andrew <marlow.and...(a)googlemail.com> wrote:
> I hope that some kind person will post chapter and verse for why it is
> wrong to say:
>
> throw std::exception("some error text");
>
> I know it's morally wrong. I always throw a derived class myself. But
> I have come across some legacy code that does this on a project I am
> working on. It was drawn to my attention because I tried compiling
> with gcc rather than the Microsoft Visual Studio compiler. gcc barfs,
> saying that there is not suitable constructor. Quite logical IMO. The
> derived classes have the ctor that's needed.
>
> It looks like studio has a constructor that it allowing it to compile.
> Or maybe its a compiler bug (there are so many). I don't know and I
> don't care why studio lets it through. I need an argument for why the
> legacy code should be corrected^H^H^H^H^H^H^H^H^Hchanged. A snippet
> from the std would be ideal.
>

18.6.1 [lib.exception]

namespace std {
class exception {
public:
exception() throw();
exception(const exception&) throw();
exception& operator=(const exception&) throw();
virtual ~exception() throw();
virtual const char* what() const throw();
};
}

Note the lack of a constructor from a C style string.


--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

From: Jonathan Mcdougall on
> Andrew Marlow wrote:
> I hope that some kind person will post chapter and verse for why it is
> wrong to say:
>
> throw std::exception("some error text");

18.6.1 does not define a constructor that takes a string:

namespace std {
class exception {
public:
exception() throw();
exception(const exception&) throw();
exception& operator=(const exception&) throw();
virtual �exception() throw();
virtual const char* what() const throw();
};
}

but 17.4.4.4/2 says: "An implementation can declare additional non-virtual
member function signatures within a class: [...] by adding a member function
signature for a member function name."

It is not "wrong" to rely on implementation-defined behavior, it only limits
you to compilers that implement this specific behavior. The usual advice is
to use standard features as much as possible and I think this is easily a case
where there's no need to rely on implementation-defined behavior.

The additional problem here is that you don't exactly know how an implementation
is handling this constructor. The easiest way would be to copy it to a
std::string member, but then you'd risk the case of throwing std::bad_alloc
instead of the original exception. On Visual C++ 2008, std::exception seems to
allocate a buffer on the heap with std::malloc().

In any case, even if it hurts to see this, you probably have better things to
do.

--
Jonathan Mcdougall


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

From: Andrew on
On 25 Feb, 08:29, Jonathan Mcdougall <jonathanmcdoug...(a)gmail.com>
wrote:
> 18.6.1 does not define a constructor that takes a string:

> but 17.4.4.4/2 says: "An implementation can declare additional non-virtual
> member function signatures within a class: [...] by adding a member function
> signature for a member function name."

It seems to be that these sections are in conflict. Section 18.6.1
says what the functions are but section 17.4.4.4 says you can add to
that list. I hope this can be cleared up in the next addition of the
std.

<paranoia>
I reckon that Microsoft are exploiting this conflict by adding a ctor
to std::exception that takes a const char*. This addition helps to
allow programmers to accidentally write code that is Microsoft-
specific whilst Microsoft say that their additional ctor still
conforms to the std.
</paranoia>

I have found a another reason why it is bad to throw std::exception.
My test harness fails at the moment because one of my tests is to test
that an exception is thrown where there is bad input. I ensure that a
std::runtime_error is caught when the error condition is presented.
But of course, that exception isn't thrown. It is dangerous for the
test harness to catch (std::exception&) since that is not specific
enough. To me, catch (std::exception&) is a catchall so whilst it is
useful in production code to prevent unexpected and silent
termination, you would not to catch it in a test harness when watching
for particular errors.

Regards,

Andrew Marlow

--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]