From: Giovanni Bajo (giovannibajo_at_[hidden])
Date: 2003-05-19 04:19:17
Guillaume Melquiond <gmelquio_at_[hidden]> wrote:
>>> void* operator new(std::size_t, stateless_integer_add*)
>>> throw std::runtime_error("Cannot allocate a stateless_integer_add");
>>>- return 0; // suppress warnings
>>>+ return (void*)1; // suppress warnings
>>> According to the paragraph 188.8.131.52-3 of the Standard, an 'operator new'
>>> can return a null pointer or throw an exception to report a failed
>>> allocation; but it isn't allowed to adopt the two behaviors.
>> Really? I don't see this specified in that very paragraph. To me, it
>> like it's saying that:
>> - an allocation function which is declared as throw() must return a null
>> pointer in case of failure.
>> - an allocation function which is not declared as throw() can call
>> new_handler, or, alternatively, throw a std::bad_alloc (or exception
>> derived from it).
> My interpretation of the standard was: an allocation function that returns
> a null pointer must have an empty exception clause and so is not allowed
> to throw any kind of exception.
You are reading it backward. It says that an allocation function declared as
throw() must return a null pointer. It does not say "*only* allocation
functions declared as throw()", nor it says "any other allocation function
must not return 0". In other words this is only an "if" clause, not a "if
and only if".
>> Since this allocation function is not declared throw(), it should throw a
>> std::bad_alloc(), not a runtime_error(). The return value does not make
>> sense here because of the throw: that statement is never reached. If
> What kind of argument is that? :-)
Probably I wasn't clear. What I'm saying is that it would be silly for the
standard to set rules for the return value of a function in a condition in
which it is supposed to throw an exception. If it said "please, make it
throw, and then return anything but zero", one would wonder why there should
be a rule about the return value when the function is not supposed to return
(at least in that code path).
> Yes the code is unreachable; but it's not enough of a reason to write bad
> code each time it's unreachable.
But do you really think that there can be a rule set by the standard for a
situation which will never happen?
And there is more: if I run the code with Comeau, I get a warning saying
that "return 0" is unreachable. So I could submit a patch to remove it
because it breaks my -Werror compilation on Comeau. It does not make sense
for the standard to prescribe such a return value, and a return statement
just to shut down an incorrect warning like this one should be activated
only for compilers suffering from this behaviour.
> The return statement is already here to suppress warnings with some
> compilers. But it also adds a warning with GCC. It's the reason why I
> suggested a patch that does a minimal change of the code: the return
> statement is not suppressed, but the return value is changed.
Yes I understand your patch, but I strongly believe that it is GCC in fault
here, not the code. If there is a fault in the code at all, it is that it's
throwing a runtime_error instead of a bad_alloc as the standard prescribes.
>> are warnings about the return value, compilers could be improved to at
>> least shut them off in such situation, or can be simply turned off in any
>> way (return 0 is ok).
>> What is the warning you get with GCC?
> GCC complains that the allocator returns a null pointer and so should have
> an empty throw() clause.
I see the warning now. I'm forwarding this message to Gabriel Dos Reis,
which is also the GCC diagnostic mantainer. Maybe he can shed some lights on
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk