Connecting Tech Pros Worldwide Forums | Help | Site Map

C++ exception context

jg
Guest
 
Posts: n/a
#1: Apr 17 '07
Can someone explain what the standard says about
exception context ? For example, suppose bar() always throw
an exception, is the value of g undefined or 1 after the handler
(empty in this case) returns ?

Thanks
JG

foo()
{
int g=0;
try {
g++;
bar(); // bar() throw an exception
} catch (...)
}
printf("g=%d\n", g);
}


Ian Collins
Guest
 
Posts: n/a
#2: Apr 17 '07

re: C++ exception context


jg wrote:
Quote:
Can someone explain what the standard says about
exception context ? For example, suppose bar() always throw
an exception, is the value of g undefined or 1 after the handler
(empty in this case) returns ?
>
Thanks
JG
>
foo()
{
int g=0;
The scope of g is foo(), so g will be 1.
Quote:
try {
g++;
bar(); // bar() throw an exception
} catch (...)
}
printf("g=%d\n", g);
}
>

--
Ian Collins.
Andre Kostur
Guest
 
Posts: n/a
#3: Apr 17 '07

re: C++ exception context


"jg" <jgu222@gmail.comwrote in news:1176764745.712480.47890
@y80g2000hsf.googlegroups.com:
Quote:
Can someone explain what the standard says about
exception context ? For example, suppose bar() always throw
an exception, is the value of g undefined or 1 after the handler
(empty in this case) returns ?
>
Thanks
JG
>
foo()
{
int g=0;
try {
g++;
bar(); // bar() throw an exception
} catch (...)
}
printf("g=%d\n", g);
}
>
>
I'm not sure why you would think that bar() would have any effect on g.
The g++ line would have finished executing before bar() is called. An
exception within a try{} block doesn't somehow invalidate the code that was
executed up to the point of the exception.
jg
Guest
 
Posts: n/a
#4: Apr 17 '07

re: C++ exception context


<<Ian Collins>>
Quote:
The scope of g is foo(), so g will be 1.
So, for the following, glb will be 2.

int glb=1;

void bar()
{
glb++;
throw 1;
}

foo()
try {
bar();
} catch (...)
}
printf("glb=%d\n", glb);
}


<< Andre Kostur>>
Quote:
>
I'm not sure why you would think that bar() would have any effect on g.
The g++ line would have finished executing before bar() is called. An
exception within a try{} block doesn't somehow invalidate the code that was
executed up to the point of the exception.
Since a compiler will allocate g into a register, that same register
may be reused (write/use) by bar(). Well, the value of the register
must be saved before being used by bar(). I am just wondering
how a compiler knows where to restore the value of g....

Thanks.
jg
used by bar(), I am wondering how a hand

Ian Collins
Guest
 
Posts: n/a
#5: Apr 17 '07

re: C++ exception context


jg wrote:
Quote:
<<Ian Collins>>
>
Quote:
>>The scope of g is foo(), so g will be 1.
>
>
So, for the following, glb will be 2.
>
Why would it be anything else?
Quote:
int glb=1;
>
void bar()
{
glb++;
throw 1;
}
>
>
>
Since a compiler will allocate g into a register, that same register
may be reused (write/use) by bar(). Well, the value of the register
must be saved before being used by bar(). I am just wondering
how a compiler knows where to restore the value of g....
>
Why would it allocate g into a register? g is a global variable, an
address in memory, that's all.

--
Ian Collins.
James Kanze
Guest
 
Posts: n/a
#6: Apr 17 '07

re: C++ exception context


On Apr 17, 1:05 am, "jg" <jgu...@gmail.comwrote:
Quote:
Can someone explain what the standard says about
exception context ? For example, suppose bar() always throw
an exception, is the value of g undefined or 1 after the handler
(empty in this case) returns ?
Quote:
foo()
{
int g=0;
try {
g++;
bar(); // bar() throw an exception
} catch (...)
}
printf("g=%d\n", g);
}
In this case, no. The usual C++ rules apply: values will
reflect all changes before the last sequence point, and none of
the changes after the next one. Anything which changes with no
intervening sequence point is up in the air. Throwing an
exception is a sequence point, but don't forget that the order
of evaluation of an expression is not specified, so something
like the following can be very problematic:

f( g++, bar() ) ;

If bar() throws, g may or may not have been incremented.

Be careful, too, because sequence points only define a partial
ordering. For example, given:
f( auto_ptr( new Toto ), bar() ) ;
one possible ordering is:
tmp = new Toto
bar()
auto_ptr( tmp )
If bar() throws, you've got a memory leak.

--
James Kanze (GABI Software) email:james.kanze@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

Howard
Guest
 
Posts: n/a
#7: Apr 17 '07

re: C++ exception context



"jg" <jgu222@gmail.comwrote in message
news:1176764745.712480.47890@y80g2000hsf.googlegro ups.com...
Quote:
foo()
{
int g=0;
try {
g++;
bar(); // bar() throw an exception
} catch (...)
Not an answer to your question, but...
shouldn't there be a { here?
Quote:
}
printf("g=%d\n", g);
}
>
-Howard


jg
Guest
 
Posts: n/a
#8: Apr 17 '07

re: C++ exception context


Thanks for answering my questions.

I also played with it and looked at the code generated. It looks
that the variables, even locals, will be stored into memory before
calling bar(), which is within try block and may throw an exception.

In a C program (not C++), a local variable usually stays within a
register
accross a call (a performance advantage over C++); whereas in C++, a
local
variable cannot stay in a register accross a call within a try block.

jg

On Apr 17, 2:51 am, James Kanze <james.ka...@gmail.comwrote:
Quote:
On Apr 17, 1:05 am, "jg" <jgu...@gmail.comwrote:
>
Quote:
Can someone explain what the standard says about
exception context ? For example, suppose bar() always throw
an exception, is the value of g undefined or 1 after the handler
(empty in this case) returns ?
foo()
{
int g=0;
try {
g++;
bar(); // bar() throw an exception
} catch (...)
}
printf("g=%d\n", g);
}
>
In this case, no. The usual C++ rules apply: values will
reflect all changes before the last sequence point, and none of
the changes after the next one. Anything which changes with no
intervening sequence point is up in the air. Throwing an
exception is a sequence point, but don't forget that the order
of evaluation of an expression is not specified, so something
like the following can be very problematic:
>
f( g++, bar() ) ;
>
If bar() throws, g may or may not have been incremented.
>
Be careful, too, because sequence points only define a partial
ordering. For example, given:
f( auto_ptr( new Toto ), bar() ) ;
one possible ordering is:
tmp = new Toto
bar()
auto_ptr( tmp )
If bar() throws, you've got a memory leak.
>
--
James Kanze (GABI Software) email:james.ka...@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

Andre Kostur
Guest
 
Posts: n/a
#9: Apr 17 '07

re: C++ exception context


jg <jgu222@gmail.comwrote in news:1176834633.458139.176790
@y5g2000hsa.googlegroups.com:
Quote:
Thanks for answering my questions.
>
I also played with it and looked at the code generated. It looks
that the variables, even locals, will be stored into memory before
calling bar(), which is within try block and may throw an exception.
>
In a C program (not C++), a local variable usually stays within a
register
accross a call (a performance advantage over C++); whereas in C++, a
local
variable cannot stay in a register accross a call within a try block.
That's a compiler quality of implementation issue, not a C++ lanugage
issue.
James Kanze
Guest
 
Posts: n/a
#10: Apr 18 '07

re: C++ exception context


jg wrote:
Quote:
I also played with it and looked at the code generated. It looks
that the variables, even locals, will be stored into memory before
calling bar(), which is within try block and may throw an exception.
Quote:
In a C program (not C++), a local variable usually stays
within a register accross a call (a performance advantage over
C++); whereas in C++, a local variable cannot stay in a
register accross a call within a try block.
It depends totally on the implementation, and exceptions have
very little effect here. Different implementations have
different conventions regarding what must be saved across the
context of a function call. Back when I was regularly working
on Intel architecture, for example, the convention was that a
function could use any register it wanted: it only had to
restore BP (the frame pointer), SP (obviously:-)) and the
segment registers. A compiler could not leave a value in a
register, and expect it to be there after a function call.
Today, on my Sparc, 16 registers are guaranteed safe, and a
compiler can leave a value in one of them even when calling a
function which may throw.

Exceptions affect optimization in two ways. First, they add
control flow paths which the compiler must take into account.
There are probably cases where this will result in saving a
value to memory, where it would otherwise be left in a register,
but they probably aren't very frequent. Secondly, it means that
any time a function which may throw is called, the stack
structure must be "clean"; it must be possible to walk back up
the stack using standard mechanisms. In practice, I don't think
that this ever affects optimization; I'm not aware of a compiler
that doesn't systematically build a clean stack structure in a
non-leaf function.

Exceptions can also have a positive effect on optimization.
First, because the test for the error condition simply isn't
present in the code of the intermediate functions, and secondly,
because the data used by the exception handling is out of line,
possibly in a separate segment, so the resulting function is
smaller, and more likely to fit into cache.

In practice, both effects seem to be pretty negligeable, and the
choix between exceptions or another error reporting mechanism
should be based on design, without regarding performance. Do
what's right; the probability that it will cause a performance
problem is so low that it's not worth worrying about.

--
James Kanze (GABI Software) email:james.kanze@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

Closed Thread