From: DeMarcus on
> A compiler *could* offer the static checking of no-throw functions as
> an extension, but you will very quickly run into practical problems.
>
> For example, should the compiler, with the feature enabled, complain
> about this function:
>
> void write_to_log(char* text) throw()
> {
> FILE* logfile = fopen("/var/log/mylogs", "a");
>
> fprintf(logfile, "%s", text);
> fclose(logfile);
> }
>
> None of the functions used here have a no-throw specification, so the
> compiler must assume they can throw an exception (unless the compiler
> has special knowledge about these functions, but then just substitute
> simple wrappers from an internal, company-specific library).
>

You're right, but the solution is actually quite simple. Either you just
keep your function as it probably looks today, without throw(), as below.

void write_to_log(char* text)
{
FILE* logfile = fopen("/var/log/mylogs", "a");

fprintf(logfile, "%s", text);
fclose(logfile);
}

Or you explain to the compiler that this is indeed a no-throw function
using throw() and try/catch(...) as below.

void write_to_log(char* text) throw()
{
try
{
FILE* logfile = fopen("/var/log/mylogs", "a");

fprintf(logfile, "%s", text);
fclose(logfile);
}
catch(...) {}
}

> The only way around that is to change the declaration of *every*
> function that is known not to throw any exceptions, which is a
> prohibitive amount of work.
>

I realize that we probably can't change existing libraries, but if we
could have an optional static check on no-throw functions, i.e. declared
throw(), it would be a start of an opening for better exception safety
without affecting those who don't want or aren't able to use it.


> {excess quoting deleted --mod}
> Bart v Ingen Schenau
>
>

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

From: ThosRTanner on

> For example, should the compiler, with the feature enabled, complain
> about this function:
>
> void write_to_log(char* text) throw()
> {
> FILE* logfile = fopen("/var/log/mylogs", "a");
>
> fprintf(logfile, "%s", text);
> fclose(logfile);
>
> }
>
> None of the functions used here have a no-throw specification, so the
> compiler must assume they can throw an exception (unless the compiler
> has special knowledge about these functions, but then just substitute
> simple wrappers from an internal, company-specific library).

I would sincerely hope none of those functions could throw, because
they're all C standard library functions, and would cause serious
problems if they threw. Any compiler should be able to safely assume
that extern "C" functions are nothrow (and that includes when it is
compiling one)

Moreover, your suggestion is a bit like the objection to const. Once
you start putting in const at the top level you have to fix everything
you call to be const correct. It's one of those bullets that needs to
be bitten. Considering the alternative is that your code will commit
suicide at runtime if you get this wrong. And for some of us, that is
not an option. As far as they affect us, exception specifications are
not only useless, they are extremely dangerous.


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

From: DeMarcus on
> BTW, as you say, you'd like an optional compiler feature. I don't
> think standard deals with such things - they define a language in
> "shall" and "shall not" terms. So a compiler could do that, as a
> quality of implementation enhancement, not the language (I could be
> wrong). Due to perf penalty of throw(), I bet you your proposal would
> end in some other mechanics, not "throw()". Perhaps some sort of a
> compiler-specific feature (e.g. through __declspec).
>

Exactly! That's the beauty of it; 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.


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

From: peter koch larsen on
On 8 Feb., 14:36, "Martin B." <0xCDCDC...(a)gmx.at> wrote:
> DeMarcus wrote:
[snip]
> > Nevertheless, just because they're renowned C++ experts, that doesn't
> > stop me from proposing enhancements to their ideas.
>
> > So if the following holds:
>
> > * A no-throw function can, without functional harm, be declared throw()
> > since such function must throw nothing, compared to a throw( MyException
> > ) that can throw more than just MyException due to templates.
>
> If throw() is enforced during runtime - i.e. there is an implicit
> catch(...)+handler added to each such function - this can have
> performance implications depending on the platform.

I assume that you mean "depending on the compiler", not the platform.
And this is true, but then complain to the compiler writers or choose
a compiler where this overhead is not present.
>
> > If that holds, then I claim an optional feature in the compiler can, by
> > means of static checking during compile-time, help finding no-throw
> > functions that throws anyway. This optional feature would be no
> > disadvantage, but only an enhancement helping programmers writing
> > exception safe code.
>
> > Please give your comments on this.
>
> 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

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

From: DeMarcus on
> Moreover, your suggestion is a bit like the objection to const. Once
> you start putting in const at the top level you have to fix everything
> you call to be const correct. It's one of those bullets that needs to
> be bitten. Considering the alternative is that your code will commit
> suicide at runtime if you get this wrong. And for some of us, that is
> not an option. As far as they affect us, exception specifications are
> not only useless, they are extremely dangerous.
>

I don't know what's more dangerous;

A) A function that throws even though it gives no-throw guarantee.
B) Programmers thinking they've created a no-throw function, when it
actually contains functions that can throw.

What I mean is that exception specifications may be dangerous, yes, but
there is an exception; the no-throw exception specification throw().


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.



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