I am trying to create an example which would allow me to catch an
exception in C++ during a call to a Fortran subroutine. I want to use
this as a crude form of error handling for my program which is mixing C
++ and Fortran using the iso_c_binding module. However, when I try to
do this, it appears that gfortran is handling the exception, rather
than letting it pass back up the stack for C++ to catch. I have
created an example of what I am trying to do and the results for each
case (exceptC.cpp and exceptF.f95).
When I compile and link the files as they are below, I get the
following result:
$ gfortran -c exceptF.f95
$ g++ -o e exceptC.cpp exceptF.o -lgfortran.a
$ ./e
terminate called after throwing an instance of 'std::domain_error'
what(): Error message because the value 3 is incorrect.
Abort trap
From the above result, it seems that when I throw the domain_error in
the "printstring" method, gfortran is handling the exception before it
can get to the catch I have in main().
To illustrate the difference, I uncomment the lines in exceptC.cpp,
which redefines fortranDriver() as a C++ function, and comment out the
extern "C" fortranDriver() definition below it. Now the code is all C+
+, I am not using gfortran in this case, so the exception is handled
properly:
$ g++ -o e exceptC.cpp
$ ./e
The following error occured: Hello
Is there some flag I can turn off in gfortran to allow the exception
to pass through back to my exception handler? Is what I am trying to
do feasible? I do not quite understand why this is happening.
Thanks,
John N.
Below are the source files:
exceptC.cpp
=============================================================
#include <iostream>
#include <stdexcept>
extern "C" void printstring(char* string_) /* equivalent: char
string[] */
{
throw std::domain_error(string_);
}
// void fortranDriver()
// {
// char a[] = "Hello";
// printstring(a);
// }
extern "C" void fortranDriver();
void driver()
{
fortranDriver();
}
int main()
{
try{
driver();
}catch(const std::exception& exception_){
std::cout << "The following error occured: " <<
exception_.what() << std::endl;
}catch(...){
std::cout << "An unknown exception occured: " << std::endl;
}
}
==============================================================
exceptF.f95
==============================================================
module strings
interface
subroutine printstring(string) bind(C, name="printstring")
use iso_c_binding, only: c_char
implicit none
character(len=1, kind=c_char) :: string
end subroutine printstring
end interface
end module strings
subroutine fortranDriver() bind(c, name="fortranDriver")
use strings
use iso_c_binding, only: c_char, c_null_char, c_int
implicit none
character(len=256, kind=c_char) :: a
integer(c_int) :: b = 3
write(a,'(a,i0,a)') "Error message because the value ", b, " is
incorrect."
call printstring(trim(a)//c_null_char)
end subroutine fortranDriver
==============================================================
|
|
0
|
|
|
|
Reply
|
John
|
10/14/2010 6:48:55 PM |
|
On 10/14/2010 09:11 PM, FX wrote:
>> $ gfortran -c exceptF.f95
>> $ g++ -o e exceptC.cpp exceptF.o -lgfortran.a
>
> Works for me:
>
> $ gfortran -c b.f90 ; /usr/local/gfortran/bin/g++ a.cpp b.o -lgfortran -lm
> $ ./a.out
> The following error occured: Error message because the value 3 is incorrect.
>
>
> gcc version 4.5.1 20100506 (prerelease) (GCC)
> Target: x86_64-apple-darwin10.3.0
>
I just tried it with 4.4.1 and 4.5.0, also works.
-- Wolfgang
--
E-mail: firstnameinitial.lastname@domain.de
Domain: yahoo
|
|
0
|
|
|
|
Reply
|
Wolfgang
|
10/14/2010 6:13:00 PM
|
|
> $ gfortran -c exceptF.f95
> $ g++ -o e exceptC.cpp exceptF.o -lgfortran.a
Works for me:
$ gfortran -c b.f90 ; /usr/local/gfortran/bin/g++ a.cpp b.o -lgfortran -lm
$ ./a.out
The following error occured: Error message because the value 3 is incorrect.
gcc version 4.5.1 20100506 (prerelease) (GCC)
Target: x86_64-apple-darwin10.3.0
--
FX
|
|
0
|
|
|
|
Reply
|
FX
|
10/14/2010 7:11:30 PM
|
|
On 10/14/2010 10:08 PM, John N. wrote:
> Are you by chance using any special configure options to build your
> gfortran? I built mine with the default options from the GFortran Wiki
> (http://gcc.gnu.org/wiki/GFortranSource), as follows:
>
> $ gfortran -v
> Configured with: ../gcc-4.6-20100925/configure --prefix=$HOME/gcc-trunk
> --enable-languages=fortran --enable-checking=release --disable-bootstrap
> Thread model: posix
> gcc version 4.6.0 20100925 (experimental) (GCC)
The 4.4.1 compiler is the one that comes with the installation:
$ gfortran -v
Using built-in specs.
Target: x86_64-suse-linux
Configured with: ../configure --prefix=/usr --infodir=/usr/share/info
--mandir=/usr/share/man --libdir=/usr/lib64 --libexecdir=/usr/lib64
--enable-languages=c,c++,objc,fortran,obj-c++,java,ada
--enable-checking=release --with-gxx-include-dir=/usr/include/c++/4.4
--enable-ssp --disable-libssp --with-bugurl=http://bugs.opensuse.org/
--with-pkgversion='SUSE Linux' --disable-libgcj --disable-libmudflap
--with-slibdir=/lib64 --with-system-zlib --enable-__cxa_atexit
--enable-libstdcxx-allocator=new --disable-libstdcxx-pch
--enable-version-specific-runtime-libs --program-suffix=-4.4
--enable-linux-futex --without-system-libunwind --with-arch-32=i586
--with-tune=generic --build=x86_64-suse-linux
Thread model: posix
gcc version 4.4.1 [gcc-4_4-branch revision 150839] (SUSE Linux)
The 4.5.0 one I built with the GFortran Wiki options
$ gfortran45 -v
Using built-in specs.
COLLECT_GCC=gfortran45
COLLECT_LTO_WRAPPER=/home/gcc/install-4.5/libexec/gcc/x86_64-unknown-linux-gnu/4.5.0/lto-wrapper
Target: x86_64-unknown-linux-gnu
Configured with: ../gcc-4_5-branch/configure
--prefix=/home/gcc/install-4.5 --enable-languages=c,c++,fortran
--enable-checking=release --disable-bootstrap
Thread model: posix
gcc version 4.5.0 20100408 (prerelease) (GCC)
I don't use 4.6 versions (yet).
-- Wolfgang
--
E-mail: firstnameinitial.lastname@domain.de
Domain: yahoo
|
|
0
|
|
|
|
Reply
|
seesig3208 (122)
|
10/14/2010 7:20:23 PM
|
|
In article <77ea616d-53bc-4724-8ddc-44465b4027a5@t8g2000yqk.googlegroups.com>,
John N. <ortp21@gmail.com> wrote:
>I am trying to create an example which would allow me to catch an
>exception in C++ during a call to a Fortran subroutine. I want to use
>this as a crude form of error handling for my program which is mixing C
>++ and Fortran using the iso_c_binding module. ...
Anyone who needs to ask that on a newsgroup doesn't have a hope in
hell of getting it to work. Sorry. Don't bother - you're wasting
your time - think of another way to do it.
If you really intend to proceed, get hold of the source of gcc
(including g++, glibc and gfortran) and investigate what is going
on. It won't be quick and it won't be easy.
Oh, and watch out for the language issues where making it 'work'
will break features of one or both languages - there are quite a
lot.
Regards,
Nick Maclaren.
|
|
-1
|
|
|
|
Reply
|
nmm1
|
10/14/2010 7:32:57 PM
|
|
On 2010-10-14 13:13:00 -0500, Wolfgang Kilian said:
> On 10/14/2010 09:11 PM, FX wrote:
>>> $ gfortran -c exceptF.f95
>>> $ g++ -o e exceptC.cpp exceptF.o -lgfortran.a
>>
>> Works for me:
>>
>> $ gfortran -c b.f90 ; /usr/local/gfortran/bin/g++ a.cpp b.o -lgfortran -lm
>> $ ./a.out
>> The following error occured: Error message because the value 3 is incorrect.
>>
>>
>> gcc version 4.5.1 20100506 (prerelease) (GCC)
>> Target: x86_64-apple-darwin10.3.0
>>
>
> I just tried it with 4.4.1 and 4.5.0, also works.
>
> -- Wolfgang
FX and Wolfgang,
Thanks for taking the time to try the example.
Are you by chance using any special configure options to build your
gfortran? I built mine with the default options from the GFortran Wiki
(http://gcc.gnu.org/wiki/GFortranSource), as follows:
$ gfortran -v
Configured with: ../gcc-4.6-20100925/configure --prefix=$HOME/gcc-trunk
--enable-languages=fortran --enable-checking=release --disable-bootstrap
Thread model: posix
gcc version 4.6.0 20100925 (experimental) (GCC)
|
|
0
|
|
|
|
Reply
|
ortp21 (6)
|
10/14/2010 8:08:16 PM
|
|
> Are you by chance using any special configure options to build your
> gfortran? I built mine with the default options from the GFortran Wiki
> (http://gcc.gnu.org/wiki/GFortranSource), as follows:
>
> $ gfortran -v
> Configured with: ../gcc-4.6-20100925/configure --prefix=$HOME/gcc-trunk
> --enable-languages=fortran --enable-checking=release --disable-bootstrap
> Thread model: posix
> gcc version 4.6.0 20100925 (experimental) (GCC)
What's your target triplet?
--
FX
|
|
0
|
|
|
|
Reply
|
coudert (470)
|
10/14/2010 8:50:57 PM
|
|
On 2010-10-14 15:50:57 -0500, FX said:
>
> What's your target triplet?
Target: x86_64-apple-darwin10.4.0
I just tried the code on Windows using the Equation.com build and it
worked correctly.
I guess this is too far over my head, like Nick Maclaren said.
|
|
0
|
|
|
|
Reply
|
John
|
10/14/2010 9:04:42 PM
|
|
On 2010-10-14 14:33:09 -0500, nmm1@cam.ac.uk said:
> In article <77ea616d-53bc-4724-8ddc-44465b4027a5@t8g2000yqk.googlegroups.com>,
> John N. <ortp21@gmail.com> wrote:
>> I am trying to create an example which would allow me to catch an
>> exception in C++ during a call to a Fortran subroutine. I want to use
>> this as a crude form of error handling for my program which is mixing C
>> ++ and Fortran using the iso_c_binding module. ...
>
> Anyone who needs to ask that on a newsgroup doesn't have a hope in
> hell of getting it to work. Sorry. Don't bother - you're wasting
> your time - think of another way to do it.
>
> If you really intend to proceed, get hold of the source of gcc
> (including g++, glibc and gfortran) and investigate what is going
> on. It won't be quick and it won't be easy.
>
> Oh, and watch out for the language issues where making it 'work'
> will break features of one or both languages - there are quite a
> lot.
>
>
> Regards,
> Nick Maclaren.
Sorry for trying. I was just attempting to not resort to doing what I
was doing before (writing errors to stdout for testing), to which you
responded (from my post: "Mixing Languages with gfortran and Visual
C++"):
>Yes, indeed. Reasonably expert people can do I/O to different files
>from the two languages, but even that has more gotchas than most
>people realise. And stdin/stdout/stderr should be handled by one
>language only, or chaos is likely.
With the example I posted today, I was just trying to handle everything
with one language (C++), I just didn't realize it was so looked down
upon.
|
|
0
|
|
|
|
Reply
|
John
|
10/14/2010 9:10:25 PM
|
|
> Target: x86_64-apple-darwin10.4.0
Then I have an easy way to guarantee you that it will work: use my own
binaries! :)
They're at http://gcc.gnu.org/wiki/GFortranBinaries#MacOS
Download the link for "Intel (x86_64)".
> I guess this is too far over my head, like Nick Maclaren said.
Nope, Nick is too pessimistic in this case, I think.
I just figured out the difference between your case and mine: you're
using the system C++ compiler with a gfortran from a different version of
GCC. I use a pair of compilers with matching version.
--
FX
|
|
0
|
|
|
|
Reply
|
FX
|
10/14/2010 9:36:58 PM
|
|
> With the example I posted today, I was just trying to handle everything
> with one language (C++), I just didn't realize it was so looked down
> upon.
Exceptions should propagate well through Fortran routines if you use
companion C++/Fortran compilers. Don't let Nick deter you from doing it!
--
FX
|
|
0
|
|
|
|
Reply
|
FX
|
10/14/2010 9:38:21 PM
|
|
On 2010-10-14 16:36:58 -0500, FX said:
> Then I have an easy way to guarantee you that it will work: use my own
> binaries! :)
>
> They're at http://gcc.gnu.org/wiki/GFortranBinaries#MacOS
> Download the link for "Intel (x86_64)".
Awesome, I just downloaded them and tried my example. It works! Thanks.
>
>> I guess this is too far over my head, like Nick Maclaren said.
>
> Nope, Nick is too pessimistic in this case, I think.
>
> I just figured out the difference between your case and mine: you're
> using the system C++ compiler with a gfortran from a different version of
> GCC. I use a pair of compilers with matching version.
Ah, so I am. When I built gfortran I did not build a corresponding g++
because I figured that the Apple gcc/g++ would be fine for my purposes,
and it would take less time to build that way haha. I will keep in mind
that the compiler pairs must be the same version for this to work as
intended.
Thanks again.
|
|
0
|
|
|
|
Reply
|
John
|
10/14/2010 9:57:51 PM
|
|
In article <i97t8d$pfa$2@news.eternal-september.org>,
FX <coudert@alussinan.org> wrote:
>> With the example I posted today, I was just trying to handle everything
>> with one language (C++), I just didn't realize it was so looked down
>> upon.
It's not looked down on - it's just so far beyond the specifications
that anything may happen.
>Exceptions should propagate well through Fortran routines if you use
>companion C++/Fortran compilers. Don't let Nick deter you from doing it!
If you are the person that I think you are, you should know better.
It is quite easy to get a single error message out of a diddy little
program when it is followed by the program terminating. But that
is NOT equivalent to getting the feature working. An expert can
make an educated guess as to what is likely to 'work' and what is
not, but most people don't. I have done that sort of trick in much
more complicated environments, but I don't do it unless I really
have to, because I know what the issues are.
You can start by considering issues like destructors, I/O buffers,
allocatable arrays, recursion, copy-in/copy-out, etc. and then
move onto the really hairy areas.
I have lost count of the times that I have had less experienced
people say that I am exaggerating such issues, only to have them
come crying to me later saying that their code has suddenly gone
bananas, the debugger is having hysterics, and they can't see why.
It's your funeral.
Regards,
Nick Maclaren.
|
|
-1
|
|
|
|
Reply
|
nmm1
|
10/14/2010 10:14:36 PM
|
|
In article <i97rk1$l0n$1@news.eternal-september.org>,
John N. <ortp21@gmail.com> wrote:
>
>Sorry for trying. I was just attempting to not resort to doing what I
>was doing before (writing errors to stdout for testing), to which you
>responded (from my post: "Mixing Languages with gfortran and Visual
>C++"):
>
>>Yes, indeed. Reasonably expert people can do I/O to different files
>>from the two languages, but even that has more gotchas than most
>>people realise. And stdin/stdout/stderr should be handled by one
>>language only, or chaos is likely.
>
>With the example I posted today, I was just trying to handle everything
>with one language (C++), I just didn't realize it was so looked down
>upon.
Now, exactly WHY did you choose to use a problematic feature of
C++ (exceptions) that has no equivalent in Fortran, rather than
just writing the message from the C++ function you called?
Regards,
Nick Maclaren.
|
|
0
|
|
|
|
Reply
|
nmm1
|
10/14/2010 10:37:46 PM
|
|
On 2010-10-14 17:37:46 -0500, nmm1@cam.ac.uk said:
> Now, exactly WHY did you choose to use a problematic feature of
> C++ (exceptions) that has no equivalent in Fortran, rather than
> just writing the message from the C++ function you called?
I am trying to write the message from the C++ function that was called
from the Fortran code. I did not realize that exceptions were a
problematic feature of C++. With the example I posted, I was just
trying to make the code use exceptions, which I commonly use in C++.
So, if I changed the C++ function called to just print out to a stream
(std::cout, for example) and return normally, than would the code be
less problematic (all I/O from C++ only)?
My only intent was for the exception to pass right through the Fortran
code, since it has no equivalent, so the calling C++ code could report
the error.
Thanks.
|
|
0
|
|
|
|
Reply
|
John
|
10/14/2010 11:25:11 PM
|
|
In article <i983gn$j2a$1@news.eternal-september.org>,
John N. <ortp21@gmail.com> wrote:
>
>> Now, exactly WHY did you choose to use a problematic feature of
>> C++ (exceptions) that has no equivalent in Fortran, rather than
>> just writing the message from the C++ function you called?
>
>I am trying to write the message from the C++ function that was called
>from the Fortran code. I did not realize that exceptions were a
>problematic feature of C++. With the example I posted, I was just
>trying to make the code use exceptions, which I commonly use in C++.
FAR too many books on computing teach techniques without describing
their limitations and dangers. It's like teaching people how to
use guns and sending them out to use them, without teaching them
safety techniques. A good test for whether a book or course is any
good is whether it DOES do that for exceptions.
Bruce Eckel "Thinking in C++" isn't bad, but doesn't cover calling
Fortran, and Bjarne Stroustrup "Programming: principles and practice
using C++" is almost certainly good, too.
>So, if I changed the C++ function called to just print out to a stream
>(std::cout, for example) and return normally, than would the code be
>less problematic (all I/O from C++ only)?
Vastly so. With the minor niggle that it is C++ and not C, it would
even be potentially standard-conforming. It is the approach that I
recommend, and will restore the ability you had to use the compilers
of your choice (insofar as you had it!)
That doesn't mean that there are NO problems, but that there are
vastly fewer and less likely ones.
>My only intent was for the exception to pass right through the Fortran
>code, since it has no equivalent, so the calling C++ code could report
>the error.
Yes. That is a very reasonable requirement, unless you know the
relevant standards and implementation techniques fairly well. In
which case you know that it would be damn near impossible to specify
or implement without breaking at least some features of one or both
languages.
Regards,
Nick Maclaren.
|
|
0
|
|
|
|
Reply
|
nmm1
|
10/15/2010 8:27:02 AM
|
|
> It is quite easy to get a single error message out of a diddy little
> program when it is followed by the program terminating. But that
> is NOT equivalent to getting the feature working.
Depends what you call "the feature". I expect that in general, mixing
broad use of C++ exceptions with broad use of inter-language programming
is a pain, and I wouldn't do it myself.
But that does not equate to it being unsupported, or working by chance or
accident, or anything like it.
In particular, I'd like to ask you why you think that mixing C++
exceptions and calling Fortran subroutines is any less safe than mixing
C++ exceptions and "extern C" functions. The latter is something people
do all the time. With one minor issue (possible buffering in the I/O
library), I do not think it is unsafe (you just need to be very careful).
> It's your funeral.
Well, on a public forum, that's the rule of the game, of course.
--
FX
|
|
0
|
|
|
|
Reply
|
FX
|
10/15/2010 11:47:53 AM
|
|
In article <i99f19$3ba$1@news.eternal-september.org>,
FX <coudert@alussinan.org> wrote:
>
>> It is quite easy to get a single error message out of a diddy little
>> program when it is followed by the program terminating. But that
>> is NOT equivalent to getting the feature working.
>
>Depends what you call "the feature". I expect that in general, mixing
>broad use of C++ exceptions with broad use of inter-language programming
>is a pain, and I wouldn't do it myself.
>
>But that does not equate to it being unsupported, or working by chance or
>accident, or anything like it.
If you are talking about the language definitions (i.e. the standards),
then they demonstrably don't support it, because the only support is for
Fortran calling C. If you are talking about compilers in general, or
even one in particular, then please post a reference to where they state
that they do, and the constraints that they impose to make it
implementable.
>In particular, I'd like to ask you why you think that mixing C++
>exceptions and calling Fortran subroutines is any less safe than mixing
>C++ exceptions and "extern C" functions. The latter is something people
>do all the time. With one minor issue (possible buffering in the I/O
>library), I do not think it is unsafe (you just need to be very careful).
I gave you a list of problematic areas. I suggest that you read the
sections of the standards about destructors (both exceptions inside them
and what happens when an exception is raised), final procedures,
C++->Fortran->C++->Fortran->C++, etc. You could then move onto the
consequences of the association rules (especially delights like
INTENT(OUT), allocatable arguments, arguments that may derive from
Fortran used when raising or handling the exception) when combined with
this sort of activity - and, if you don't start gibbering at that point,
you haven't understood them.
That may sound arrogant but is, regrettably, accurate. I worked as
a sort of consultant on one of the only two relatively modern projects
I know of that attempted to support exception handling in a multi-language
context, and the issues are evil to a degree that few people realise.
Bjarne didn't have major headaches with the C++ design because it was
conceptually easy, and that was starting from just one, conceptually
trivial, language.
Regards,
Nick Maclaren.
|
|
0
|
|
|
|
Reply
|
nmm12 (898)
|
10/15/2010 12:32:36 PM
|
|
|
17 Replies
408 Views
(page loaded in 0.176 seconds)
Similiar Articles: Detecting floating-point error code from Windows Gfortran - comp ...This is done by disabling floating point exceptions, and ... This we can do in Windows: C:\gfortran\clf\mxcsr>type mxcsr.f90 module mxcsr use ISO_C_BINDING ... Windows API programming with gfortran or g95 - comp.lang.fortran ...... standard f03 in any compiler that implements ISO_C_BINDING. The example quoted above shows that gfortran ... bit Windows - comp.lang.fortran Enable alignement exception ... Something bad happened to my gfortran installation - comp.lang ...C:\gfortran\clf\mxcsr>type test5.f90 program test5 use ISO_C_BINDING implicit none type ... and invalid operation exceptions ... this that gfortran doesn't catch ... problem with mixed c and fortran code - comp.lang.fortran ...With early versions of gfortran accepting the iso_c_binding, character functions were not ... environment (including the standard units), memory management, exception ... bad pointer exception - comp.lang.c++Something bad happened to my gfortran installation - comp.lang ..... round ... catching std::exception by value - comp.lang.c++.moderated ... Bad use of stringstream ... Wide Preprocessor Concatenation - comp.lang.c++.moderated ...... with double underscores" by using a ... lang.fortran One strong point of gfortran is the ability to use the C ... catching std::exception by value - comp.lang.c++.moderated ... GUI for Fortran programs - comp.lang.fortranCompile and run using: gfortran -c do_fortran.f90 g++ -o ... Handling exceptions (even close) is equally ... Today, I would you use the iso_c_binding module ... Where did Fortran go? - comp.lang.fortran... Fortran 2008 is a minor update - with the exception ... some of the same computers I've run Fortran using > gfortran ... be in a compilable form with the compiler catching ... Problems opening Wordpad from java (but notepad works just fine ...... rt.exec(command1); Process p2 = rt.exec(command2); } catch (Exception ... Sockets in gfortran? - comp.lang.fortran The stuff attached here is just the C ... Unix Systems Programming Newbie - exec format error - comp.unix ...I'm writting a C/sockets client interface on Solaris. ... m reusing a common > >library function to catch and log ... WRITE_ERROR ... Windows API programming with gfortran or g95 ... segmentation fault (SIGSEGV) - comp.lang.fortran> > -- > steve Oh, sry, gFortran is the actual comiler ... very similar names, the compiler is likely to catch ... [Question] Install gcc -Arithmetic Exception (core dumped ... intent(out) for pointer dummy argument - comp.lang.fortran ...For example, pointer targets are an exception to the ... compiler to reject the code, but that's a catch 22 ... end steven-corrells-macbook-pro:foo sjc$ gfortran foo.f90 -c ... naming convention for class attributes (member data)? - comp.lang ..."That's some catch, that Catch-22," he observed. "It's ... Seems like a nice convention, the one exception being the 'i'. ... struct test { int dud; char data ... use ISO_C_BINDING ... fortran - gfortran, DLL, underscore - Stack OverflowThe ISO C Binding gives a lot of control, so if this doesn't work ... GFortran equivalent of ieee_exceptions Win32 API and gfortran - Application Forum at ObjectMix.comC:\gfortran\test>gfortran --v Using built-in specs. ... use ISO_C_BINDING implicit none integer(C_LONG ... disable-win32-registry --enable-sjlj-exceptions ... 7/27/2012 1:29:51 PM
|