From: Maxim Yegorushkin on
On Thu, 30 Jun 2005 22:27:44 +0400, David Abrahams
<dave(a)boost-consulting.com> wrote:

[]

>> Using exceptions, what influences the memory?
>> And what influences the program size?
>
> That's also implementation dependent. There is generally no dynamic
> memory associated with exception-handling.

Not sure if exception throwing is exception-handling, but g++ allocates
exceptions on the heap.

http://savannah.gnu.org/cgi-bin/viewcvs/gcc/gcc/libstdc%2B%2B-v3/libsupc%2B%2B/eh_alloc.cc?rev=HEAD&content-type=text/vnd.viewcvs-markup

--
Maxim Yegorushkin
<firstname.lastname(a)gmail.com>

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

From: Thiago R. Adams on
> Broken preconditions should almost always be handled with an assert
> and not an exception. An exception will usually cause a great deal of
> code to be executed before you get a chance to diagnose the problem.

In much cases asserts work as comentary only;
for example:

void f(pointer *p){
assert(p != 0);
p->f();
}

With exceptions the code will be response the error.

The TC++PL has an example:

template <classX , classA > inline void Assert(A assertion) {
if (!assertion ) throw X();
}

If think that the most useful is:
template <classX , classA > inline void Assert(A assertion) {
DebugBreak(); // stops debug
if (!assertion ) throw X();
}

void f2(int* p) {
// ARG_CHECK is an constant: true for checks args
Assert<Bad_arg>(ARG_CHECK || p !=0 );
}

If code is correct the all callers will be test for arguments.
Then I can remove this test. (ARG_CHECK) But is nescessary?

When use throw and when use asserts?
Two cases:
void func(vector &v, int *p) {
if (p == 0)
throw bad_arg(); // why not? because this functions alread throws
v.push_back(p); // push can throw right?
}

void func(vector &v, int *p) throw() {
// maybe is better, becase this function no throw
// it has only one contract with callers in debug and release
assert(p != 0);

// yes I can use reference but is only an example :)
*p = v.size() + 10;
}

I think that is a long and important topic.
Performance in exceptions is important to decide the use.
My coworks says: "If we doesn't kwown the behavior and performance
penalities of exceptions, we will use returns codes, because returns
codes is more simple and is known"


Thanks!
(and sorry my english is not so good)


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

From: David Abrahams on
"Maxim Yegorushkin" <firstname.lastname(a)gmail.com> writes:

> On Thu, 30 Jun 2005 22:27:44 +0400, David Abrahams
> <dave(a)boost-consulting.com> wrote:
>
> []
>
>>> Using exceptions, what influences the memory?
>>> And what influences the program size?
>>
>> That's also implementation dependent. There is generally no dynamic
>> memory associated with exception-handling.
>
> Not sure if exception throwing is exception-handling, but g++ allocates
> exceptions on the heap.
>
> http://savannah.gnu.org/cgi-bin/viewcvs/gcc/gcc/libstdc%2B%2B-v3/libsupc%2B%2B/eh_alloc.cc?rev=HEAD&content-type=text/vnd.viewcvs-markup

AFAICT those exceptions are being "dynamically" allocated out of
static memory, in

static one_buffer emergency_buffer[EMERGENCY_OBJ_COUNT];

That looks like the "magic memory" I was referring to. Am I missing
something?

--
Dave Abrahams
Boost Consulting
www.boost-consulting.com

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

From: David Abrahams on
"Thiago R. Adams" <thiago.adams(a)gmail.com> writes:

>> Broken preconditions should almost always be handled with an assert
>> and not an exception. An exception will usually cause a great deal of
>> code to be executed before you get a chance to diagnose the problem.
>
> In much cases asserts work as comentary only;
> for example:
>
> void f(pointer *p){
> assert(p != 0);
> p->f();
> }

No, they work to stop program execution at the earliest point of
detection of the error.

> With exceptions the code will be response the error.

If preconditions are broken, your program state is broken, by
definition. Trying to recover is generally ill-advised.

> The TC++PL has an example:

That doesn't make it right :)

> template <classX , classA > inline void Assert(A assertion) {
> if (!assertion ) throw X();
> }
>
> If think that the most useful is:
> template <classX , classA > inline void Assert(A assertion) {
> DebugBreak(); // stops debug

Stop execution so I can debug the program. Good!

> if (!assertion ) throw X();
> }

If the assertion fails when there is no debugger, how do you expect
the program to recover?

> void f2(int* p) {
> // ARG_CHECK is an constant: true for checks args
> Assert<Bad_arg>(ARG_CHECK || p !=0 );
> }
>
> If code is correct the all callers will be test for arguments.
> Then I can remove this test. (ARG_CHECK) But is nescessary?

I don't understand the question.

> When use throw and when use asserts?

Use asserts to detect that the invariants you have designed into your
program are broken. Use throw to indicate that a function will not be
able to fulfill its usual postconditions, and when the immediate
caller is not very likely to be able to handle the error directly and
continue (otherwise, use error return codes and the like).

> Two cases:
> void func(vector &v, int *p) {
> if (p == 0)
> throw bad_arg(); // why not? because this functions alread throws

Why not? Because, I presume, passing 0 is a precondition violation.
It depends on what you put in your documentation. If you say, "you
must pass me a non-null pointer," then use an assert. If you say, "if
you pass a null pointer I'll throw," well, then throw. However, the
former is usually the better course of action.

> v.push_back(p); // push can throw right?

Yes. So what?

> }
>
> void func(vector &v, int *p) throw() {
> // maybe is better, becase this function no throw
> // it has only one contract with callers in debug and release
> assert(p != 0);

Even if it were not nothrow, it would have only one contract.

> // yes I can use reference but is only an example :)
> *p = v.size() + 10;
> }
>
> I think that is a long and important topic.
> Performance in exceptions is important to decide the use.
> My coworks says: "If we doesn't kwown the behavior and performance
> penalities of exceptions, we will use returns codes, because returns
> codes is more simple and is known"

Yes, it's a common FUD. It's easy to do some experiments to get a
feeling for the real numbers.

Do they know the cost in correctness and maintainability of using
return codes?

--
Dave Abrahams
Boost Consulting
www.boost-consulting.com

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

From: Alf P. Steinbach on
* David Abrahams -> Thiago R. Adams:
>
> >
> > If think that the most useful is:
> > template <classX , classA > inline void Assert(A assertion) {
> > DebugBreak(); // stops debug
>
> Stop execution so I can debug the program. Good!
>
> > if (!assertion ) throw X();
> > }
>
> If the assertion fails when there is no debugger, how do you expect
> the program to recover?

That's actually a good _C++_ question... ;-)

First, the reason why one would like to 'throw' in this case, which is
usually not to recover in the sense of continuing normal execution, but
to recover enough to do useful logging, reporting and graceful exit on
an end-user system with no debugger and other programmer's tools
(including, no programmer's level understanding of what goes on).

Why that is a problem in C++: the standard exception hierarchy is not
designed. Uh, I meant, it's not designed with different degrees of
recoverability in mind. At best you can use std::runtime_error for
"soft" (in principle recover-and-continue-normally'able) exceptions, and
classes derived otherwise from std::exception for "hard" exceptions, but
in practice people tend to not restrict themselves to
std::runtime_error, and the Boost library is an example of this common
practice -- the standard's own exception classes are also examples.

So, if you want a really "hard" exception in C++, one that is likely to
propagate all the way up to the topmost control level, you'll have to
use something else than a standard exception.

And even that non-standard exception might be caught (and not rethrown)
by a catch(...) somewhere. Which is not as unlikely as it might seem.
E.g., as I recall, ScopeGuard does that in its destructorý.

Well, then, why not use std::terminate instead? After all, that's what
it's for, isn't it? And it's configurable.

But no, that's not what it's for. Calling std::terminate does not
guarantee RAII cleanup as a "hard" exception would. In short, I know of
no good portable solution to this problem in standard C++, and thinking
of how extremely easily it could have been supported in the design of
the standard exception classes (there was even existing practice from
earlier languages indicating how it should be) it's very frustrating.


ý) One might argue that calling std::terminate is the only reasonable
failure handling in a destructor, even for ScopeGuard-like objects.
But the standard already provides that draconian measure for the
situation where it's really needed, where you would otherwise have a
double exception (which does not exist in C++). Doing it explicitly
just removes a measure of control from the client code programmer.

--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?

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

First  |  Prev  |  Next  |  Last
Pages: 1 2 3 4 5 6 7 8 9 10 11 12
Next: C++/CLI limitations?