From: DeMarcus on
Seungbeom Kim wrote:
> DeMarcus wrote:
>>>> I fully agree that some mechanism to statically enforce/analyse the
>>>> no-throw guarantee would be very welcome!
>>>
>>> The problem is one of technology. With the linking model we use now,
>>> it is impossible. And changing the model does not really change
>>> anything.
>>> Determining if a function can throw is to the best of my knowledge not
>>> possible, and if it is, surely it will be computationally to expensive
>>> to be usable.
>>> Just take a simple function like:
>>>
>>> std::vector<int> f()
>>> {
>>> std::vector<int> res(200000);
>>> return res;
>>> }
>>>
>>> You can't determine if that function might throw unless you know what
>>> new_handler is installed.
>>>
>>> /Peter
>>>
>>
>> Just to not diverge from the original thread I want to emphasize that
>> the idea is to track no-throw functions only. [...]
> [...]
>>
>> * If a function is declared throw() it is a no-throw function. If it is
>> not declared throw() it may throw whatever, according to the compiler.
>>
>> * If a throw()-declared function contains any function that is not
>> declared throw(), we get a warning.
>
> I'm afraid you don't seem to understand. Take the following function
> for example:
>
> std::vector<int> f() throw()
> {
> std::vector<int> res(200000);
> return res;
> }
>
> Peter's argument was that it was impossible for the compiler to
> determine whether a function (like the one above) might throw.
> How should your optional compiler feature respond to this?
>

Maybe I miss something, but wouldn't the compiler be able to see that
std::vector's constructor is declared without throw()?

The std::vector's constructor is not declared throw(), hence the
compiler can easily see that f() might throw, or actually crash since
f() is declared throw() which will stop all exceptions. In your example
the compiler would give a warning that f() is declared no-throw but
calls functions not declared no-throw.

However, something that I don't know is the following.

std::vector<int> f() throw()
{
try
{
std::vector<int> res(200000);
return res;
}
catch(...) {}
}

Will the copy to the return value be embraced by the try/catch(...)?
I don't know. Does anyone know?

One thing I know though, is that no-throw operations should not return
values that must use a copy constructor (see Exceptional C++ by Herb
Sutter, Item 10). That is why pop_back() never returns the popped value.

I mean, already here we see the effect of the static check. If someone,
from a no-throw function, returns a value that uses the copy constructor
we will get a warning.


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

From: DeMarcus on
>>
>> * If a function is declared throw() it is a no-throw function. If it is
>> not declared throw() it may throw whatever, according to the compiler.
>>
>> * If a throw()-declared function contains any function that is not
>> declared throw(), we get a warning.
>
> And there is the problem. You need a way to assure the compiler that a
> function call will not result in an exception even though the function
> does not have a throw spec.
>

Yes, for instance std::vector::pop_back() does not have a throw spec,
and I would deal with it like this.

void f() throw()
{
try { myVector.pop_back(); } catch(...) {}
}

Now I have assured the compiler that the myVector.pop_back() call will
not result in an exception even though the function does not have a
throw spec.

>
> Just as an example, how many library (both standard and third party)
> have throw specs on their dtors? You cannot just add a throw spec
> yourself because that changes the interface and may result in unwanted
> added code.
>

Good point. The destructors could be checked but probably hard to do
anything about if they are embedded in a class, like for instance:

class Foo
{
public:
~Foo() throw() {}

private:
Bar b;
};

class Bar
{
public:
~Bar() {}
};


I don't know how to deal with that.


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

From: Francis Glassborow on
DeMarcus wrote:
>>> Maybe I should clarify that the standard does *not* need to be touched.
>>> Not even the libraries have to be touched!
>>>
>>> The only thing I'm asking for is an optional feature in the compiler
>>> that warns me if a function, declared throw(), contains any function not
>>> declaring throw(). That's it! The rest I can do myself.
>>
>>
>> Then just about every function will issue a warning because there are
>> far too many library functions that cannot throw bot have no exception
>> spec on their declaration. You would get so many warnings with no good
>> way to fix them that you would soon get tired of it.
>>
>
> You have a point!
>
> However, as for my own code I would start fix it in this end;
>
> 1. Turn on the compiler flag.
> 2. In my own project (not libraries), start declare throw() for the
> no-throw functions.
> 3. For each function changed to throw(), check if we get a compiler
> warning. If so, in the function's contents, embrace non-project
> functions with try/catch(...). E.g.
> try { myVector.pop_back(); } catch(...) {}
> 4. Iterate over all no-throw functions in the project until all are
> declared throw().
>
> The try/catch(...) will tell the compiler that this library function can
> be seen as declared throw(), hence the warning will disappear.

By doing the compiler's work for it and also losing any potential
efficiency gains that might have been achieved.
>
> Now, to get back to your comment, correct me if I'm wrong, but the only
> places where we would get warnings we cannot fix is in template
> libraries (like the STL), where a function declared throw() uses
> functions not declared throw(). As I understand it, throw() is sparsely
> used in template libraries, hence we would probably not get that many
> warnings.

And so every use of an STL function would be prone to causing you a problem.


Sorry but this is simply not the way to go. I know that WG21 has been
considering a nothrow attribute to assist compilers.

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

From: Francis Glassborow on
DeMarcus wrote:
>>
>> And part ofg that mechanism will have to be a way to reassure the
>> compiler that a function call will not throw (or to put it another way,
>> if it does then the programmer takes full responsibility)
>>
>> Just for the purposes of exposition:
>>
>> int foo(int); // programmer has not declared foo
>> // not to throw
>>
>> int bar() nothrow {
>> int i(nothrow foo(0)); // assures compiler that
>> // this call will not thorw
>> // more code
>> }
>>
>> I think that some such mechanism is necessary to deal with the many
>> existing libraries where perfectly reasonable functions that will not
>> throw have not been declared as not throwing.
>>
>>
>
> Yes, you're right, but to make it simple, i.e. keep the fingers away
> from the standard, we can solve it like this for now.
>
> int foo(int); // programmer has not declared foo
> // not to throw
>
> int bar() throw() {
> try {
> int i(foo(0));
> }
> catch(...) {} // assures compiler that
> // this call will not thorw
> // more code
> }

But that is exactly the kind of added complexity that I do not want to
clutter my code with.

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

From: Goran on
On Feb 9, 7:41 pm, "Martin B." <0xCDCDC...(a)gmx.at> wrote:
> I understand it could be like with const. A const function doesn't
> guarantee *anything* (const-cast, mutable members), but still it's a
> useful tool!

I disagree on that very much. const/mutable work good because both are
quite visible through language __syntax__ and stand out like a sore
thumb (that is , it's entirely compile-time issue). Not at all so with
your throw() idea because code that can throw is entirely down to
behavior defined by the code/programmer (that is, it's very much a run-
time issue).

Goran.


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