Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

newbie question: exceptions

64 views
Skip to first unread message

Jivanmukta

unread,
Aug 13, 2019, 10:34:20 AM8/13/19
to
I am learning C++ and I have a question: why:

throw exception();

and not:

throw new exception();

Jivanmukta

unread,
Aug 13, 2019, 10:38:34 AM8/13/19
to
W dniu 13.08.2019 o 16:34, Jivanmukta pisze:
Does it make sense to code:

MyClass *myObj = MyClass();

instead of:

MyClass *myObj = new MyClass();

Szyk Cech

unread,
Aug 13, 2019, 11:02:04 AM8/13/19
to
NTG: alt.comp.lang.learn.c-c++

Bo Persson

unread,
Aug 13, 2019, 11:02:18 AM8/13/19
to
On 2019-08-13 at 16:38, Jivanmukta wrote:
> W dniu 13.08.2019 o 16:34, Jivanmukta pisze:
>> I am learning C++ and I have a question: why:
>>
>> throw exception();
>>
>> and not:
>>
>> throw new exception();

You can do either - throw an exception object or throw a pointer.

In the latter case you have to catch a pointer and also remember to
delete it somewhere. Extra work. And an extra allocation.

So most people prefer the first version.


>
> Does it make sense to code:
>
> MyClass *myObj = MyClass();
>
> instead of:
>
> MyClass *myObj = new MyClass();

No. You can just do

MyClass myObj;

and be done with it. No need for pointers here.


Bo Persson

Öö Tiib

unread,
Aug 13, 2019, 11:03:30 AM8/13/19
to
On Tuesday, 13 August 2019 17:38:34 UTC+3, Jivanmukta wrote:
> W dniu 13.08.2019 o 16:34, Jivanmukta pisze:
> > I am learning C++ and I have a question: why:
> >
> > throw exception();
> >
> > and not:
> >
> > throw new exception();

First throws exception, second throws pointer to exception.
Second does allocate memory dynamically and you need to delete the
caught pointer to exception somewhere after throwing for not to leak it
but the object's lifetime is not bound to catch site.
So with second there are more work both for you and for the resulting
program but also more flexibility.
Otherwise there are no why and why not level of difference.

> Does it make sense to code:
>
> MyClass *myObj = MyClass();

No. It is usually syntax error, and when not takes unusual
design of MyClass. Typical is:

MyClass myObj{};

> instead of:
>
> MyClass *myObj = new MyClass();

There is similar extra work, like it was with exceptions. It is up to
you, programmer to decide if that is needed by your program
design or not. I can't tell it from abstract one-liners.

Szyk Cech

unread,
Aug 13, 2019, 11:03:35 AM8/13/19
to
Ju throw objekt of any walue - not limited tu pointers...

Bonita Montero

unread,
Aug 13, 2019, 11:03:44 AM8/13/19
to
Because new might throw an exception itself (bad_alloc) and you would
throw a pointer and not an object itself.

Where the memory for the exception-object is allocated is unspecified.
Can anyone tell what the usual implementations are?

Bonita Montero

unread,
Aug 13, 2019, 11:39:21 AM8/13/19
to
> Beginners should never use "new" in modern C++.

If the use shared_ptr<T> or unique_ptr<T> with the constructor
-parameters for the new'd object and get a complex compiler-error
because of the parmeters don't fit in the headers of the smart-
pointer-classes they'd better should use raw pointers and new
and ignore that their code is not memory-collapse-safe for the
first time.

red floyd

unread,
Aug 13, 2019, 12:33:30 PM8/13/19
to
Aside from what everyone else has said...

Because C++ isn't Java.

Melzzzzz

unread,
Aug 13, 2019, 8:37:47 PM8/13/19
to
Except if you don't work with MFC ;)
>


--
press any key to continue or any other to quit...
U ničemu ja ne uživam kao u svom statusu INVALIDA -- Zli Zec
Na divljem zapadu i nije bilo tako puno nasilja, upravo zato jer su svi
bili naoruzani. -- Mladen Gogala

Jivanmukta

unread,
Aug 14, 2019, 4:06:19 AM8/14/19
to
W dniu 13.08.2019 o 17:02, Bo Persson pisze:
> On 2019-08-13 at 16:38, Jivanmukta wrote:
>> W dniu 13.08.2019 o 16:34, Jivanmukta pisze:

>>> throw exception();

>
> You can do either - throw an exception object or throw a pointer.
>
> In the latter case you have to catch a pointer and also remember to
> delete it somewhere. Extra work. And an extra allocation.
>
> So most people prefer the first version.

Do you mean that in the line:

throw exception();

I create automatic object of a class exception?

Alf P. Steinbach

unread,
Aug 14, 2019, 4:25:20 AM8/14/19
to
You're creating a temporary, that's copied/moved somewhere.

Throwing is anyway a high cost operation. Whether it involves dynamic
allocation internally depends on the C++ implementation.

Your responsibility ends with the creation of the temporary. Any memory
management after that is automatic. Of course, it relies on assumed
correctness of copy constructor and/or move constructor.


Cheers!,

- ALf

Jorgen Grahn

unread,
Aug 14, 2019, 6:18:49 AM8/14/19
to
Like someone else hinted, if this surprises you and you come from a
Java background, you should probably stop and read up on the
differences between the languages. C++ and Java are very different
in this area.

/Jorgen

--
// Jorgen Grahn <grahn@ Oo o. . .
\X/ snipabacken.se> O o .

James Kuyper

unread,
Aug 14, 2019, 8:41:34 AM8/14/19
to
On 8/14/19 4:25 AM, Alf P. Steinbach wrote:
> On 14.08.2019 10:06, Jivanmukta wrote:
>> W dniu 13.08.2019 o 17:02, Bo Persson pisze:
>>> On 2019-08-13 at 16:38, Jivanmukta wrote:
>>>> W dniu 13.08.2019 o 16:34, Jivanmukta pisze:
>>
>>>>> throw exception();
>>
>>>
>>> You can do either - throw an exception object or throw a pointer.
>>>
>>> In the latter case you have to catch a pointer and also remember to
>>> delete it somewhere. Extra work. And an extra allocation.
>>>
>>> So most people prefer the first version.
>>
>> Do you mean that in the line:
>>
>> throw exception();
>>
>> I create automatic object of a class exception?
>
> You're creating a temporary, that's copied/moved somewhere.
>
> Throwing is anyway a high cost operation. Whether it involves dynamic
> allocation internally depends on the C++ implementation.

True, but only in the same sense that it is equally true of passing an
argument to a function - an implementation is free to dynamically
allocate space for function parameters, so long as it does so in a way
that's transparent to the user, and the same is true of exception
objects. Any method that user code could use to detect the fact that
it's dynamically allocated (for instance, by trying to deallocate it)
has behavior not defined by the standard.

"The name declared in an exception-declaration is local to the
handler..." (6.3.3p4 "Block Scope").
"Block-scope variables not explicitly declared static, thread_local, or
extern have automatic storage duration. ..." (6.7.3p1).
Exception declarations are not allowed to have storage class specifiers
(18p1), so none of those exceptions apply.

Alf P. Steinbach

unread,
Aug 14, 2019, 1:40:14 PM8/14/19
to
On 14.08.2019 14:41, James Kuyper wrote:
> On 8/14/19 4:25 AM, Alf P. Steinbach wrote:
>> On 14.08.2019 10:06, Jivanmukta wrote:
>>> W dniu 13.08.2019 o 17:02, Bo Persson pisze:
>>>> On 2019-08-13 at 16:38, Jivanmukta wrote:
>>>>> W dniu 13.08.2019 o 16:34, Jivanmukta pisze:
>>>
>>>>>> throw exception();
>>>
>>>>
>>>> You can do either - throw an exception object or throw a pointer.
>>>>
>>>> In the latter case you have to catch a pointer and also remember to
>>>> delete it somewhere. Extra work. And an extra allocation.
>>>>
>>>> So most people prefer the first version.
>>>
>>> Do you mean that in the line:
>>>
>>> throw exception();
>>>
>>> I create automatic object of a class exception?
>>
>> You're creating a temporary, that's copied/moved somewhere.
>>
>> Throwing is anyway a high cost operation. Whether it involves dynamic
>> allocation internally depends on the C++ implementation.
>
> True, but only in the same sense that it is equally true of passing an
> argument to a function

No, I didn't write a meaningless truism, even though I was a member of
the Tautology Club while I was a member of the Tautology Club. Sorry if
it gave the appearance of being babble.

From C++11 you can get what's functionally a shared pointer to an
exception object, via `std::current_exception`.

Whatever it refers to must necessarily be dynamically allocated, and an
implementation might, for simplicity, do that up front at the throw
point, rather than deferring the dynamic allocation in the hope that it
will not be needed and that copying the object will be cheaper.


[snip]
> Any method that user code could use to detect the fact that
> it's dynamically allocated (for instance, by trying to deallocate it)
> has behavior not defined by the standard.

There's no need to detect. With `current_exception` one knows it's
dynamically allocated. Deallocation is a matter of destroying all owning
smart pointers to that exception object. Which does not guarantee to
deallocate immediately, but ensures that proper cleanup is done.


> "The name declared in an exception-declaration is local to the
> handler..." (6.3.3p4 "Block Scope").
> "Block-scope variables not explicitly declared static, thread_local, or
> extern have automatic storage duration. ..." (6.7.3p1).
> Exception declarations are not allowed to have storage class specifiers
> (18p1), so none of those exceptions apply.

Yes, but it seems that here you went out on a tangent, into the land of
irrelevancies.


Cheers!,

- Alf

James Kuyper

unread,
Aug 14, 2019, 7:48:09 PM8/14/19
to
On 8/14/19 1:39 PM, Alf P. Steinbach wrote:
> On 14.08.2019 14:41, James Kuyper wrote:
>> On 8/14/19 4:25 AM, Alf P. Steinbach wrote:
>>> On 14.08.2019 10:06, Jivanmukta wrote:
...
>>>> Do you mean that in the line:
>>>>
>>>> throw exception();
>>>>
>>>> I create automatic object of a class exception?
>>>
>>> You're creating a temporary, that's copied/moved somewhere.
>>>
>>> Throwing is anyway a high cost operation. Whether it involves dynamic
>>> allocation internally depends on the C++ implementation.
>>
>> True, but only in the same sense that it is equally true of passing an
>> argument to a function
...
> From C++11 you can get what's functionally a shared pointer to an
> exception object, via `std::current_exception`.
>
> Whatever it refers to must necessarily be dynamically allocated, and an
> implementation might, for simplicity, do that up front at the throw
> point, rather than deferring the dynamic allocation in the hope that it
> will not be needed and that copying the object will be cheaper.
>
>
> [snip]
>> Any method that user code could use to detect the fact that
>> it's dynamically allocated (for instance, by trying to deallocate it)
>> has behavior not defined by the standard.
>
> There's no need to detect. With `current_exception` one knows it's
> dynamically allocated. Deallocation is a matter of destroying all owning
> smart pointers to that exception object. Which does not guarantee to
> deallocate immediately, but ensures that proper cleanup is done.


It's true that

"The referenced object shall remain valid at least as long as there is
an exception_ptr object that refers to it." (21.8.6p8).

Depending upon where it's stored, the lifetime of the exception_ptr
returned by current_exception() might be a lot longer than than the end
of the block for that exception's handler. Therefore, the referenced
object cannot, in general, be an object with automatic storage duration
local to that block. However, other parts of that same clause say:

"Returns: An exception_ptr object that refers to ... or a copy of the
currently handled exception ... It is unspecified whether the return
values of two successive calls to current_exception refer to the same
exception object. [ Note: That is, it is unspecified whether
current_exception creates a new copy each time it is called. — end note
] If the attempt to copy the current exception object throws an
exception, the function returns an exception_ptr object that refers to
the thrown exception or, if this is not possible, to an instance of
bad_exception. [ Note: The copy constructor of the thrown exception may
also fail, so the implementation is allowed to substitute a
bad_exception object to avoid infinite recursion."

Are those the semantics of a shared pointer to the current exception? As
I understand the concept, a shared pointer to something actually points
at that thing, rather than at a copy of that thing.

Given that the referenced object can be a copy of the currently handled
exception, rather than the exception itself, the lifetime of the
referenced object doesn't impose any requirements on how the exception
itself is handled. It's entirely feasible for dynamic allocation to only
occur when needed to store that copy.

>> "The name declared in an exception-declaration is local to the
>> handler..." (6.3.3p4 "Block Scope").
>> "Block-scope variables not explicitly declared static, thread_local, or
>> extern have automatic storage duration. ..." (6.7.3p1).
>> Exception declarations are not allowed to have storage class specifiers
>> (18p1), so none of those exceptions apply.
>
> Yes, but it seems that here you went out on a tangent, into the land of
> irrelevancies.

Those clauses demonstrate that the exception itself must have automatic
storage duration; a fact very relevant to the point I was making.
Allocating it dynamically is only allowed insofar as covered by the
as-if rule (the same is true of function parameters, for similar reasons).

Alf P. Steinbach

unread,
Aug 14, 2019, 11:13:21 PM8/14/19
to
It's the semantics of a shared pointer.

Pointing to either the current exception or a copy.


> As
> I understand the concept, a shared pointer to something actually points
> at that thing, rather than at a copy of that thing.

Yes. I have the feeling that in your mind you felt that you were making
a point here, arguing against something. You're not, but, provided that
my interpretation is correct, you wouldn't have written it if you were
aware of that.

To convince yourself that you were making a meaningless statement, try
to quote the context that you were thinking of.


> Given that the referenced object can be a copy of the currently handled
> exception, rather than the exception itself, the lifetime of the
> referenced object doesn't impose any requirements on how the exception
> itself is handled. It's entirely feasible for dynamic allocation to only
> occur when needed to store that copy.

Yes.


>>> "The name declared in an exception-declaration is local to the
>>> handler..." (6.3.3p4 "Block Scope").
>>> "Block-scope variables not explicitly declared static, thread_local, or
>>> extern have automatic storage duration. ..." (6.7.3p1).
>>> Exception declarations are not allowed to have storage class specifiers
>>> (18p1), so none of those exceptions apply.
>>
>> Yes, but it seems that here you went out on a tangent, into the land of
>> irrelevancies.
>
> Those clauses demonstrate that the exception itself must have automatic
> storage duration;

No, they don't.

The temporary T constructed in the throw statement, if there is one, has
automatic storage duration, that's all.

Then there is an exception object, let's call it E, created as a copy of
T, that conceptually lives somewhere else: it does conceptually not live
on the stack, because the stack is unwinded, all variables in the
abandoned frame destroyed, but it might be copied/moved around.

Details. The first quote is about the scope of the name declared in a
`catch` clause. That says nothing about T or E. The second quote is
about block scope variables. T, if there is a T, is a temporary so it's
not a variable, and E doesn't have block scope.

One implementation strategy, at the machine code level, could be to just
let that temporary continue to live down in the old abandoned stack
frame until a handler is found, whence it can be copied up into the
exception handling stack frame.

But that's just me speculating: it's a technical possibility, not a
strategy I've seen by inspecting compiler code. The only C++ compiler
code I've looked at was g++, when they used original C function
declarations. The idea then was to implement an exception handling
control structure I'd argued for, but the code was so ugly I left it.


> a fact very relevant to the point I was making.

Not sure what the point was. :)


> Allocating it dynamically is only allowed insofar as covered by the
> as-if rule (the same is true of function parameters, for similar reasons).

Yes, which means it's allowed.


Cheers!,

- Alf

Tim Rentsch

unread,
Aug 18, 2019, 1:07:31 AM8/18/19
to
Tiib <oot...@hot.ee> writes:

> On Tuesday, 13 August 2019 17:38:34 UTC+3, Jivanmukta wrote:
> [...]
>
>> Does it make sense to code:
>>
>> MyClass *myObj = MyClass();
>
> No. It is usually syntax error,

In most cases a diagnostic is required, but assuming MyClass
is a class (or struct), and there is no funny preprocessor
stuff going on, it is never a syntax error.

Öö Tiib

unread,
Aug 18, 2019, 2:18:33 AM8/18/19
to
I can demo that it is ill-formed on most trivial case:
http://coliru.stacked-crooked.com/a/aa95b9b7035de3c3

Öö Tiib

unread,
Aug 18, 2019, 3:05:48 AM8/18/19
to
Ok. I think I got it ... you meant it is not syntax error but
semantic error.

Tim Rentsch

unread,
Aug 18, 2019, 8:18:46 AM8/18/19
to
Tiib <oot...@hot.ee> writes:
Right.

Rosario19

unread,
Aug 24, 2019, 2:29:56 AM8/24/19
to
i am for not use exceptions

C++ can have some problems
if one doesn't know how/when the memory of the program
is dinamically created and free
and if one doesn't know how many leak his/her progam has
but for remain it seems ok

Melzzzzz

unread,
Aug 24, 2019, 7:31:02 AM8/24/19
to
Exceptions does not produce leaks except if you use MFC.

red floyd

unread,
Aug 26, 2019, 1:29:48 PM8/26/19
to
If you design your classes properly and use RAII, you will
not have leaks.

Also, by using the Standard Library, you should be able to avoid
using new/delete directly, again, avoiding leaks.


0 new messages