std::exit Ambiguity?

J

JKop

An excerpt from the Standard:


4 Calling the function
void exit(int);
declared in <cstdlib> (18.3) terminates the program without leaving the
current block and hence without
destroying any objects with automatic storage duration (12.4). If exit is
called to end a program during
the destruction of an object with static storage duration, the program has
undefined behavior.


Now take the following code:


#include <cstdlib>
#include <iostream>

class Blah
{
public:

~Blah()
{
std::cout << "\nBlah's Destructor!\n";
}
};


int main()
{
Blah blah;

{ exit(0); }
}


I myself would've thought that blah's destructor *would* have been called...
after all, its scope isn't that of "the current block".


Thoughts?


-JKop
 
J

JKop

The destructor doesn't get called in the following either:

#include <cstdlib>
#include <iostream>

void Cow()
{
exit(0);
}

int main()
{
Blah blah;

Cow();
}
 
J

John Harrison

JKop said:
An excerpt from the Standard:


4 Calling the function
void exit(int);
declared in <cstdlib> (18.3) terminates the program without leaving the
current block and hence without
destroying any objects with automatic storage duration (12.4). If exit is
called to end a program during
the destruction of an object with static storage duration, the program has
undefined behavior.


Now take the following code:


#include <cstdlib>
#include <iostream>

class Blah
{
public:

~Blah()
{
std::cout << "\nBlah's Destructor!\n";
}
};


int main()
{
Blah blah;

{ exit(0); }
}


I myself would've thought that blah's destructor *would* have been called...
after all, its scope isn't that of "the current block".


Thoughts?

I think you're misreading the standard. It doesn't say that destruction
depends upon whether an object is in the current block or not. It says that
destructors for automatic objects are not called BECAUSE the current block
isn't left. In other words no destructors for automatic objects will be
called, period.

If you want to end a program and have automatic object destructors called
then throw an exception.

john
 
N

NULL

4 Calling the function
I think you're misreading the standard. It doesn't say that destruction
depends upon whether an object is in the current block or not. It says
that destructors for automatic objects are not called BECAUSE the
current block isn't left. In other words no destructors for automatic
objects will be called, period.

Hmm... yeah... I suppose... but I'd prefer if the Standard were more
explicit. For example:

without destroying any and all objects with automatic storage, including
those defined in other blocks.
If you want to end a program and have automatic object destructors
called then throw an exception.

john


Helpful as ever, thanks!

You mean throw an exception and not catch in?

What I'm doing is calling a function from main. I want this function to have
the "power" to end the program.


As in:


void SomeFunc()
{
//something goes wrong

throw int();
}


int main()
{
SomeFunc();
}


What happens when an exception isn't caught... I take it there's a certain
"std::" function called, yeah?

But then again, seeing as how there's no destructors to be called in my code
above, is there anything... wrong... with calling exit? And let's say for
instance that you have an "std::string" object with automatic storage, if
you call exit() are you invoking UB by not having its destructor called? And
even though the destructor isn't called, is the memory still deallocated for
the object?


-JKop
 
J

John Harrison

Hmm... yeah... I suppose... but I'd prefer if the Standard were more
explicit. For example:

without destroying any and all objects with automatic storage, including
those defined in other blocks.



Helpful as ever, thanks!

You mean throw an exception and not catch in?

What I'm doing is calling a function from main. I want this function to have
the "power" to end the program.


As in:


void SomeFunc()
{
//something goes wrong

throw int();
}


int main()
{
SomeFunc();
}


What happens when an exception isn't caught... I take it there's a certain
"std::" function called, yeah?

Not sure, std::terminate I think, look it up. But in practice it might be
better to do this

int main()
{
try
{
SomeFunc();
}
catch (...)
{
}
}

just to make sure that you exit main in the normal way. This should ensure
that global objects get destructed too.
But then again, seeing as how there's no destructors to be called in my co de
above, is there anything... wrong... with calling exit? And let's say for
instance that you have an "std::string" object with automatic storage, if
you call exit() are you invoking UB by not having its destructor called?

No I don't think so.
And
even though the destructor isn't called, is the memory still deallocated for
the object?

That's system dependent I think. Most O/S will return all allocated memory
to the system upon program exit (after all whoever heard of a program that
didn't leak memory). Windows and Unix both do this.

john
 
J

Jacek Dziedzic

What I'm doing is calling a function from main. I want this function to have
the "power" to end the program.


As in:


void SomeFunc()
{
//something goes wrong

throw int();
}


int main()
{
SomeFunc();
}


What happens when an exception isn't caught... I take it there's a certain
"std::" function called, yeah?

But then again, seeing as how there's no destructors to be called in my code
above, is there anything... wrong... with calling exit? And let's say for
instance that you have an "std::string" object with automatic storage, if
you call exit() are you invoking UB by not having its destructor called? And
even though the destructor isn't called, is the memory still deallocated for
the object?

The memory will be eventually freed by the operating system (hopefully).

You could always

class ExcTerminate {};

void SomeFunc() {
throw ExcTerminate();
}

int main() {
// ...
try {
// ...
}
catch(ExcTerminate) {
return 0;
}
// ...
}

- J.
 
J

JKop

class ExcTerminate {};
void SomeFunc() {
throw ExcTerminate();
}

int main() {
// ...
try {
// ...
}
catch(ExcTerminate) {
return 0;
}
// ...
}


You're a mind reader - I just did that 5 minutes ago!


-JKop
 
V

Vyacheslav Kononenko

How about:
struct ExcTerminate {
int code;
ExcTerminate(int retcode) : code(retcode){}
};

int main()
{
try {
...
}
catch(ExcTerminate exc){
return exc.code;
}
...
}

Regards,
Vyacheslav
 
J

JKop

struct ExcTerminate {
int code;
ExcTerminate(int retcode) : code(retcode){}
};

int main()
{
try {
...
}
catch(ExcTerminate exc){
return exc.code;
}
...
}


Even better!


-JKop
 
R

Rolf Magnus

Hmm... yeah... I suppose... but I'd prefer if the Standard were more
explicit. For example:

without destroying any and all objects with automatic storage, including
those defined in other blocks.

That's what it says. You quoted it yourself: "... and hence without
destroying any objects with automatic storage duration". Nothing about
objects within the current block, just "any objects".
You mean throw an exception and not catch in?

What I'm doing is calling a function from main. I want this function to
have the "power" to end the program.


As in:


void SomeFunc()
{
//something goes wrong

throw int();
}


int main()
{
SomeFunc();
}


What happens when an exception isn't caught... I take it there's a certain
"std::" function called, yeah?

But then again, seeing as how there's no destructors to be called in my
code above, is there anything... wrong... with calling exit? And let's say
for instance that you have an "std::string" object with automatic storage,
if you call exit() are you invoking UB by not having its destructor
called? And even though the destructor isn't called, is the memory still
deallocated for the object?

Depends on the OS, but usually, the memory is freed. But think about other
things, like a file which buffered data has to be written to before being
closed or a database connection that needs to be shut down properly.
 
R

Ron Natalie

What I'm doing is calling a function from main. I want this function to have
the "power" to end the program.

No you have to catch it in main. It's unspecified if the stack is unwound on the way to
terminate.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,579
Members
45,053
Latest member
BrodieSola

Latest Threads

Top