I'm wondering if it is safe to throw an C++ exception inside an OMP critical section.
#pragma omp critical (my_critical_section)
{
...
throw my_exception("failed")
...
}
g++ does not complain. I'm puzzled because it complains about return
statements inside the critical section. It returns the error: invalid exit from OpenMP structured block
when I write
#pragma omp critical (my_critical_section)
{
...
return;
...
}
So, why is it OK to leave the critical section with an exception, but it is not OK to leave it with a return statement?
No, it is not OK to leave a critical section with exceptions. g++
does not complain in this case but it silently inserts an implicit try/catch
around the block of the critical section. For example the following code:
#pragma omp critical (my_crit)
{
throw 3;
}
gets lowered by the OpenMP processor of GCC 4.7 into:
#pragma omp critical (my_crit)
__builtin_GOMP_critical_name_start (&.gomp_critical_user_my_crit);
try
{
D.20639 = __cxa_allocate_exception (4);
try
{
MEM[(int *)D.20639] = 3;
}
catch
{
__cxa_free_exception (D.20639);
}
__cxa_throw (D.20639, &_ZTIi, 0B);
}
catch
{
<<<eh_must_not_throw (terminate)>>>
}
__builtin_GOMP_critical_name_end (&.gomp_critical_user_my_crit);
Reaching the implicit built-in catch-all handler <<<eh_must_not_throw (terminate)>>>
results in quite ungraceful termination:
terminate called after throwing an instance of 'int'
Abort trap: 6
The implicit try/catch
is inserted regardless of the presence of an outer try/catch
construct, ie the exception would never ever leave the critical
section.
The OpenMP standard mandates, that if an exception is thrown within most OpenMP constructs ( parallel
, section
, master
, single
, for
, critical
, task
, etc.), execution must resume within the same construct and that the same thread must catch the exception. Violation of this restriction leads to non-conformant OpenMP code and g++
simply enforces the conformance by inserting try/catch
blocks with termination handlers inside all such constructs.
As for the error when a return
statement is present, OpenMP defines a strcutured block in C/C++ as:
For C/C++, an executable statement, possibly compound, with a single entry at the top and a single exit at the bottom, or an OpenMP construct.
and also (for all languages):
The point of exit cannot be a branch out of the structured block .
Obviously return
constitutes a branch ouf of the block, different from simply falling of the bottom of the block.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.