Reputation: 3014
I have different (but not satisfactory) behavior when trying to catch exceptions raised by a c++ function which is called by a fortran subroutine, itself called by a c++ main.
The fortran subroutine in testf.f
source file is:
subroutine testf(simul)
external simul
call simul(0)
end
and the c++ part (main and function) is in main.cpp
source file:
#include <iostream>
using namespace std;
typedef void (*fun_t)(int *ind);
extern "C" void testf_(fun_t);
void cppsimul(int *i);
int main() {
cout << "in main\n";
try
{
testf_(cppsimul);
}
catch (int e)
{
cout << "Caught exception\n";
}
return 0;
}
void cppsimul(int *i)
{
cout << "in cppsimul\n";
throw 0;
}
When compiled with a pure gnu toolchain (g++ (Ubuntu 9.4.0-1ubuntu1~20.04.3) 9.4.0) under Linux/x86_64, I got the following result:
$ gfortran -c testf.f
$ g++ main.cpp testf.o -o main
$ ./main
in main
in cppsimul
Caught exception
in fact the -fexceptions
switch does not seem to be necessary.
When compiled with a conda 24.7.1 toolchain (clang 18.1.4, gfortran 13.2.0), on a x86_64 mac, I get:
$ gfortran -c testf.f
$ clang++ main.cpp testf.o -o main
$ ./main
in main
in cppsimul
libc++abi: terminating due to uncaught exception of type int
zsh: abort ./main
Caught exception
When compiled with a conda 24.7.1 toolchain (clang 18.1.4, gfortran 13.2.0), on a arm64 mac, I get:
$ gfortran -c testf.f
$ clang++ main.cpp testf.o -o main
$ ./main
in main
in cppsimul
zsh: trace trap ./main
and when run in lldb I have the following trace:
in main
in cppsimul
Process 88839 stopped
* thread #1, queue = 'com.apple.main-thread', stop reason = EXC_BREAKPOINT (code=1, subcode=0x18e794944)
frame #0: 0x000000018e794944 libunwind.dylib`libunwind::UnwindCursor<libunwind::LocalAddressSpace, libunwind::Registers_arm64>::step(bool) + 504
libunwind.dylib`libunwind::UnwindCursor<libunwind::LocalAddressSpace, libunwind::Registers_arm64>::step:
-> 0x18e794944 <+504>: brk #0xc471
0x18e794948 <+508>: pacib x16, x8
0x18e79494c <+512>: b 0x18e794a84 ; <+824>
0x18e794950 <+516>: mov x0, #0x0
Target 0: (main) stopped.
For both architectures, I have a normal output (the reference is Linux above) if I replace clang++
by /usr/bin/clang++
but it has no sense to do this for a bigger project (Apple /usr/bin/clang++ has version 15.0.0, from command line tools 15.1) as all dependencies of conda packages have versions which are compatible with the toolchain (clang 18.1.4).
What could be the problem with the conda toolchain? Probably a mismatch between system's /usr/lib/libc++
and conda libc++, but how could it be, as builds of conda packages are supposed to be coherent with each-other and with the system libraries.
I would be grateful if an expert could give be some explanations.
Upvotes: -1
Views: 105
Reputation: 31271
Fortran and C do not support exception. You C++ function throwing an exception leads to undefined behavior.
Create a wrapper of this function in C++ that returns a error code and catches the exceptions internally.
This is the way C++ and C/Fortran can cooperate.
The fact that some compilers can handle it in non-standard way does not mean it is something universal or supported.
Upvotes: 1