Discussion:
using iargc()/getarg() form C
Satish Balay
2005-02-22 16:40:57 UTC
Permalink
It appears that gfortran now has support for iargc()/getarg() from
fortran [by name transofrmation]. However Some mixed language codes
that support fortran - use these functions from C.

Is there a plan to provide the above symbols as well?
getarg_() -> _gfortran_getarg_i4()
iargc_() -> _gfortran_iargc()

Thanks,
Satish
----

In gcc-3.4
asterix:/home/balay>nm -o /usr/lib/gcc/i386-redhat-linux/3.4.2/libg2c.a | egrep \(iargc\|getarg\) |grep ' T '
/usr/lib/gcc/i386-redhat-linux/3.4.2/libg2c.a:Lgetarg.o:00000000 T getarg_
/usr/lib/gcc/i386-redhat-linux/3.4.2/libg2c.a:Liargc.o:00000000 T iargc_
/usr/lib/gcc/i386-redhat-linux/3.4.2/libg2c.a:getarg_.o:00000000 T G77_getarg_0
/usr/lib/gcc/i386-redhat-linux/3.4.2/libg2c.a:iargc_.o:00000000 T G77_iargc_0

gcc-4
[***@localhost ~]$ nm -o /usr/lib/gcc/i386-redhat-linux/4.0.0/libgfortranpreview.a | egrep \(iargc\|getarg\) |grep ' T '
nm: bessel.o: no symbols
nm: c99_functions.o: no symbols
nm: erf.o: no symbols
/usr/lib/gcc/i386-redhat-linux/4.0.0/libgfortranpreview.a:args.o:00000000 T _gfortran_getarg_i4
/usr/lib/gcc/i386-redhat-linux/4.0.0/libgfortranpreview.a:args.o:000000a8 T _gfortran_getarg_i8
/usr/lib/gcc/i386-redhat-linux/4.0.0/libgfortranpreview.a:args.o:000000d1 T _gfortran_iargc
/usr/lib/gcc/i386-redhat-linux/4.0.0/libgfortranpreview.a:args.o:00000000 T _gfortrani_getarg_i4
Satish Balay
2005-02-22 19:24:30 UTC
Permalink
Post by Satish Balay
It appears that gfortran now has support for iargc()/getarg() from
fortran [by name transofrmation]. However Some mixed language codes
that support fortran - use these functions from C.
Is there a plan to provide the above symbols as well?
getarg_() -> _gfortran_getarg_i4()
iargc_() -> _gfortran_iargc()
According to http://gcc.gnu.org/ml/fortran/2005-02/msg00141.html
command_argument_count() and get_command_argument() are the correct
things to use.

How about providing the appropriate names as well instead of the
modified ones? so this standard defined versions are easily detected
and used from C as well?

command_argument_count__ -> _gfortran_get_command_argument_i4
get_command_argument__ -> _gfortran_get_command_i4

thanks,
Satish

-------
[***@localhost junk]$ nm -o /usr/lib/gcc/i386-redhat-linux/4.0.0/libgfortranpreview.a | grep command
nm: bessel.o: no symbols
nm: c99_functions.o: no symbols
nm: erf.o: no symbols
/usr/lib/gcc/i386-redhat-linux/4.0.0/libgfortranpreview.a:args.o:000000ee T _gfortran_get_command_argument_i4
/usr/lib/gcc/i386-redhat-linux/4.0.0/libgfortranpreview.a:args.o:00000210 T _gfortran_get_command_argument_i8
/usr/lib/gcc/i386-redhat-linux/4.0.0/libgfortranpreview.a:args.o:0000026e T _gfortran_get_command_i4
/usr/lib/gcc/i386-redhat-linux/4.0.0/libgfortranpreview.a:args.o:000003a6 T _gfortran_get_command_i8
/usr/lib/gcc/i386-redhat-linux/4.0.0/libgfortranpreview.a:args.o:000000ee T _gfortrani_get_command_argument_i4
/usr/lib/gcc/i386-redhat-linux/4.0.0/libgfortranpreview.a:args.o:0000026e T _gfortrani_get_command_i4
[***@localhost junk]$
Steve Kargl
2005-02-22 19:42:39 UTC
Permalink
Post by Satish Balay
Post by Satish Balay
It appears that gfortran now has support for iargc()/getarg() from
fortran [by name transofrmation]. However Some mixed language codes
that support fortran - use these functions from C.
Is there a plan to provide the above symbols as well?
getarg_() -> _gfortran_getarg_i4()
iargc_() -> _gfortran_iargc()
According to http://gcc.gnu.org/ml/fortran/2005-02/msg00141.html
command_argument_count() and get_command_argument() are the correct
things to use.
Both intrinsics are from Fortran 2003 and so are technically
extension to the Fortran 95 language.

I would certainly use these instead of iargc/getarg.
Post by Satish Balay
How about providing the appropriate names as well instead of the
modified ones? so this standard defined versions are easily detected
and used from C as well?
command_argument_count__ -> _gfortran_get_command_argument_i4
get_command_argument__ -> _gfortran_get_command_i4
This probably won't happen. What are we to do if someone
uses the -i8 option? Should gfortran remap the C entry
point to the *_i8 gfortran procedures?

There is nothing stopping you from wrapping the gfortran
procedure in a C function.
--
Steve
Satish Balay
2005-02-22 23:23:01 UTC
Permalink
Post by Steve Kargl
Both intrinsics are from Fortran 2003 and so are technically
extension to the Fortran 95 language.
I would certainly use these instead of iargc/getarg.
Could you tell me what are the correct symbols in the fortran
library that I can call directly from C?

What I've listed isn't correct. [and the name mangling is not
interpretable].

I have:
[***@localhost junk]$ gfortran -v
Using built-in specs.
Target: i386-redhat-linux
Configured with: ../configure --prefix=/usr --mandir=/usr/share/man --infodir=/usr/share/info --enable-shared --enable-threads=posix --enable-checking=release --with-system-zlib --enable-__cxa_atexit --disable-libunwind-exceptions --with-gxx-include-dir=/usr/include/c++/3.4.3 --enable-languages=c,c++,java,f95 --enable-java-awt=gtk --host=i386-redhat-linux
Thread model: posix
gcc version 4.0.0 20050217 (Red Hat 4.0.0-0.27)
Post by Steve Kargl
This probably won't happen. What are we to do if someone
uses the -i8 option? Should gfortran remap the C entry
point to the *_i8 gfortran procedures?
Well - intel compilers are doing something - without having some wierd
name mapping [and still are able to support both -i4 & -i8]

And for calls from C - the things would be -i4 anyway - so I was
hoping the default names are i4 versions.
Post by Steve Kargl
There is nothing stopping you from wrapping the gfortran
procedure in a C function.
yeah I can modify my stuff - but if possible its better that previous
codes just worked - without modifications [i.e external codes from
other sources]

thanks,
Satish
Steve Kargl
2005-02-23 01:59:27 UTC
Permalink
Post by Satish Balay
Post by Steve Kargl
Both intrinsics are from Fortran 2003 and so are technically
extension to the Fortran 95 language.
I would certainly use these instead of iargc/getarg.
Could you tell me what are the correct symbols in the fortran
library that I can call directly from C?
I just looked at the implementation of iargc. You can't
get at the command line arguments with the gfortran
functions from a C program. Well, you might be able to
get them, but we need more details in exactly what
you're doing.

Most C programs have

int main(int argc, char *argv[])

as the entry point. Is there some reason you can't just
use the usual C idiom.
--
Steve
Satish Balay
2005-02-23 04:00:56 UTC
Permalink
Post by Steve Kargl
Post by Satish Balay
Could you tell me what are the correct symbols in the fortran
library that I can call directly from C?
I just looked at the implementation of iargc. You can't
get at the command line arguments with the gfortran
functions from a C program. Well, you might be able to
get them, but we need more details in exactly what
you're doing.
Ok - here is the usage with gcc3

##########################################
# cat arg.c
#include <stdio.h>
extern int iargc_();
extern void getarg_(int*,char*,int);

void foo_()
{
int num, len, status;
char name[25];
num = 0;
getarg_(&num,&name[0],25);
name[24]=0;
printf("Program name: %s\n",name);
num = iargc_();
printf("No of args: %d\n",num);
}
# cat arg-test.f
program main
call foo()
end
# gcc -c arg.c
# g77 arg-test.f arg.o -o arg-test
# ./arg-test option1 option2
Program name: ./arg-test
No of args: 2
#

##########################################

This usage works with gcc4 with the following change:
iargc_ -> _gfortran_iargc
getarg_ -> _gfortran_getarg_i4

# gcc -c arg.c
# gcc4 -c arg.c
# gfortran arg-test.f arg.o -o arg-test
# ./arg-test option1 option2
Program name: ./arg-test
No of args: 3
#

[ I guess the off by 1 issue is fixed in CVS ]
[with gcc version 4.0.0 20041019 (Red Hat 4.0.0-0.8)]

##########################################

I guess I could just use the above and be done with it.

But now that 'command_argument_count() & get_command_argument()' are
standerdised - perhaps I should use them? If so, maybe my code will be
cleaner and will work across all compilers that implement this
standard with less mess than the current status quo [which is special
code for almost all compilers]

to check it out I tried:
# cat arg.f
program test
integer num, len, status,cmd_count
character*7 value
num = 0
call GET_COMMAND_ARGUMENT(num, value, len, status)
print*, value
print*, len
print*, status
cmd_count = COMMAND_ARGUMENT_COUNT()
print*, cmd_count
end

# gfortran arg.f
# gfortran -c arg.f
# nm -o arg.o
arg.o: U _gfortran_filename
arg.o: U _gfortran_get_command_argument_i4
arg.o: U _gfortran_iargc
arg.o: U _gfortran_ioparm
arg.o: U _gfortran_line
arg.o: U _gfortran_st_write
arg.o: U _gfortran_st_write_done
arg.o: U _gfortran_transfer_character
arg.o: U _gfortran_transfer_integer
arg.o:00000000 T MAIN__

Obviously I'm looking for some symbols with names
'get_command_argument' & 'command_argument_count but' I don't see
that. [somehow '_gfortran_iargc' crept in]. So this interface doesn't
looks easy to use for my purpose.
Post by Steve Kargl
Most C programs have
int main(int argc, char *argv[])
as the entry point. Is there some reason you can't just
use the usual C idiom.
This kind of usage is found in libraries that provide c/fortran
interfaces - but do most of the internal stuff in C.

Satish
Steve Kargl
2005-02-23 04:24:13 UTC
Permalink
Post by Satish Balay
Post by Steve Kargl
Post by Satish Balay
Could you tell me what are the correct symbols in the fortran
library that I can call directly from C?
I just looked at the implementation of iargc. You can't
get at the command line arguments with the gfortran
functions from a C program. Well, you might be able to
get them, but we need more details in exactly what
you're doing.
iargc_ -> _gfortran_iargc
getarg_ -> _gfortran_getarg_i4
You don't need to do the above.
Post by Satish Balay
# gcc -c arg.c
# gcc4 -c arg.c
# gfortran arg-test.f arg.o -o arg-test
This is crucial. You must link the final program with the
gfortran command.

kargl[218] ~/gcc/work/bin/gcc -c gr.c
kargl[219] gfc -o foo foo.f90 gr.o
kargl[220] ./foo 1 2 3
3
kargl[221] cat gr.c
extern int _gfortran_iargc(void);
int iargc_(void)
{
return _gfortran_iargc();
}
kargl[222] cat foo.f90
program main
integer i
i = iargc()
print *, i
end

I leave getargs to you to wrap.
--
Steve
Satish Balay
2005-02-23 14:24:12 UTC
Permalink
Post by Steve Kargl
Post by Satish Balay
Post by Steve Kargl
Post by Satish Balay
Could you tell me what are the correct symbols in the fortran
library that I can call directly from C?
I just looked at the implementation of iargc. You can't
get at the command line arguments with the gfortran
functions from a C program. Well, you might be able to
get them, but we need more details in exactly what
you're doing.
iargc_ -> _gfortran_iargc
getarg_ -> _gfortran_getarg_i4
You don't need to do the above.
Post by Satish Balay
# gcc -c arg.c
# gcc4 -c arg.c
# gfortran arg-test.f arg.o -o arg-test
This is crucial. You must link the final program with the
gfortran command.
Is this because of the automatic linking to -lgfortranbegin? [we try
to detect all compiler libraries - so that any compiler c/c++/fortran
will work as the linker. sometimes this is messy and doesn't always
work]
Post by Steve Kargl
kargl[218] ~/gcc/work/bin/gcc -c gr.c
kargl[219] gfc -o foo foo.f90 gr.o
kargl[220] ./foo 1 2 3
3
kargl[221] cat gr.c
extern int _gfortran_iargc(void);
int iargc_(void)
{
return _gfortran_iargc();
}
kargl[222] cat foo.f90
program main
integer i
i = iargc()
print *, i
end
Hmm - here you are calling iargc() from fortran. This isn't my
usage. And I thought you don't need wrappers for this usage..

# gfortran -c foo.f90
# nm foo.o
U _gfortran_filename
U _gfortran_iargc
U _gfortran_ioparm
U _gfortran_line
U _gfortran_st_write
U _gfortran_st_write_done
U _gfortran_transfer_integer
00000000 T MAIN__

Satish
Post by Steve Kargl
I leave getargs to you to wrap.
Satish Balay
2005-02-23 14:36:29 UTC
Permalink
Post by Satish Balay
Post by Steve Kargl
This is crucial. You must link the final program with the
gfortran command.
Is this because of the automatic linking to -lgfortranbegin? [we try
to detect all compiler libraries - so that any compiler c/c++/fortran
will work as the linker. sometimes this is messy and doesn't always
work]
Ah.. I should have said - we usually try to match the linker to the
language that has the entry point - aka main().

Satish
Steve Kargl
2005-02-23 15:10:07 UTC
Permalink
Post by Satish Balay
Post by Satish Balay
Post by Steve Kargl
This is crucial. You must link the final program with the
gfortran command.
Is this because of the automatic linking to -lgfortranbegin? [we try
to detect all compiler libraries - so that any compiler c/c++/fortran
will work as the linker. sometimes this is messy and doesn't always
work]
Ah.. I should have said - we usually try to match the linker to the
language that has the entry point - aka main().
This is why you need to use gfortran. Look at libgfortran/runtime/main.c.
--
Steve
Satish Balay
2005-02-23 15:26:09 UTC
Permalink
Post by Steve Kargl
Post by Satish Balay
Post by Satish Balay
Post by Steve Kargl
This is crucial. You must link the final program with the
gfortran command.
Is this because of the automatic linking to -lgfortranbegin? [we try
to detect all compiler libraries - so that any compiler c/c++/fortran
will work as the linker. sometimes this is messy and doesn't always
work]
Ah.. I should have said - we usually try to match the linker to the
language that has the entry point - aka main().
This is why you need to use gfortran. Look at libgfortran/runtime/main.c.
This isn't an issue with gcc/g77/gfortran [coluld be with other compilers]
asterix:/home/balay/junk/arg>gcc4 -c arg.c
asterix:/home/balay/junk/arg>gfortran -c arg-test.f
asterix:/home/balay/junk/arg>gcc4 arg-test.o arg.o -L/usr/lib/gcc/i386-redhat-linux/4.0.0 -lgfortranbegin -lgfortranpreview
asterix:/home/balay/junk/arg>

But this is drifting elseware. The primary purpose I started this
thread is:

- If possible - have gfortran support iargc/iargv usage from C,
similar to gcc3 - this way curent codes don't break when distributions
upgrade from gcc3 to gcc4 [fedora is contemplating this move]. But
looks like internal library/symbol organization to support -i8 is
breaking this.

- if possible use command_argument_count() & get_command_argument() -
but with internal name trasformations - gfortran is requiring a
separete ifdef [in user code] anyway - so not much benifit here.

Satish
Steve Kargl
2005-02-23 16:45:33 UTC
Permalink
Post by Steve Kargl
kargl[221] cat gr.c
extern int _gfortran_iargc(void);
int iargc_(void)
{
return _gfortran_iargc();
}
kargl[222] cat foo.f90
program main
integer i
i = iargc()
print *, i
end
Whoops. I sent the wrong foo program. Try this one.

program main
integer i, iargc
external iargc ! This line is important.
i = iargc()
print *, i
end

troutmask:kargl[220] /usr/tmp/sgk/bin/gfc -o foo -static foo.f90
/var/tmp/cc8VmR4v.o(.text+0x9): In function `MAIN__':
: undefined reference to `iargc_'
collect2: ld returned 1 exit status
troutmask:kargl[221] /usr/tmp/sgk/bin/gfc -o foo -static foo.f90 gr.o
troutmask:kargl[222] ./foo 1 2 3
3
troutmask:kargl[228] /usr/tmp/sgk/bin/gfc -static -c foo.f90
troutmask:kargl[229] nm foo.o
0000000000000000 T MAIN__
U _gfortran_filename
U _gfortran_ioparm
U _gfortran_line
U _gfortran_st_write
U _gfortran_st_write_done
U _gfortran_transfer_integer
U iargc_
--
Steve
Satish Balay
2005-02-23 19:56:17 UTC
Permalink
Post by Steve Kargl
Whoops. I sent the wrong foo program. Try this one.
program main
integer i, iargc
external iargc ! This line is important.
i = iargc()
print *, i
end
troutmask:kargl[220] /usr/tmp/sgk/bin/gfc -o foo -static foo.f90
: undefined reference to `iargc_'
collect2: ld returned 1 exit status
troutmask:kargl[221] /usr/tmp/sgk/bin/gfc -o foo -static foo.f90 gr.o
troutmask:kargl[222] ./foo 1 2 3
3
troutmask:kargl[228] /usr/tmp/sgk/bin/gfc -static -c foo.f90
troutmask:kargl[229] nm foo.o
0000000000000000 T MAIN__
U _gfortran_filename
U _gfortran_ioparm
U _gfortran_line
U _gfortran_st_write
U _gfortran_st_write_done
U _gfortran_transfer_integer
U iargc_
I guess I understand this code - but this usage is not relavant to to
the stated problem. Its relavant only if the wrapper code is in
gfortran library.

thanks,
Satish
Steve Kargl
2005-02-23 20:10:29 UTC
Permalink
Post by Satish Balay
I guess I understand this code - but this usage is not relavant to to
the stated problem. Its relavant only if the wrapper code is in
gfortran library.
I guess I don't understand your stated problem. You're
trying to use a Fortran runtime library routine that
requires initialization via the Fortram main_ entry point,
which isn't used unless you link with gfortran.
--
Steve
Satish Balay
2005-02-23 20:49:33 UTC
Permalink
Post by Steve Kargl
Post by Satish Balay
I guess I understand this code - but this usage is not relavant to to
the stated problem. Its relavant only if the wrapper code is in
gfortran library.
I guess I don't understand your stated problem. You're
trying to use a Fortran runtime library routine that
requires initialization via the Fortram main_ entry point,
which isn't used unless you link with gfortran.
If you look at the sample code I posted earlier
http://gcc.gnu.org/ml/fortran/2005-02/msg00277.html

The entry point is fortran - but calls to iargc_() are from C. This
mode is used for example by MPICH [discussed in an earlier thread] to
support MPI fortran bindings. And the hope was that packages like
MPICH shoudn't need patches to work with gfortran [when distributions
transition from gcc3 to gcc4]

The problem was clarified again at:
http://gcc.gnu.org/ml/fortran/2005-02/msg00288.html

My recomendation is to have non-changed names in the fortran library
correspond to the default mode '-i4, -r4' - and mangled names for 'i8
-r8'

i.e foobar [=> foobar_i4]
foobar_i8 [separate symbol to support -i8]

currently you have;
foobar_i4
foobar_i8

gfortran can do all the correct things in such a case aswell. [for all
fortran code with -i4 or -i8]

Satish
FX Coudert
2005-02-23 22:01:40 UTC
Permalink
Post by Satish Balay
but calls to iargc_() are from C
Yes, and that means the C code using iargc_ is relying on the guts of a
compiler (which is, of course, not a right thing to do). I know that
this doesn't help you, but I sincerely think such code was modified in a
portable way: as an example, declare a nargs variable, make sure both
fortran and C code can access it, and at the beginning of the (fortran)
code, call iargc (or f2003 equivalent) to set this nargs variable. Now,
this should work whatever your (reasonnable) compiler is.

For the problem at stake, a choice has to be made about where we want to
set the limit between useful compatibility and things that should go.
Now, my opinion (and be aware that I'm no guru) is that having to export
all kinds of compatibility symbols is not the way we want gfortran to
go. If we wanted total source/binary compatibility, we're gonna end up
nowhere (or we're gonna end up rewritting g77).
Post by Satish Balay
My recomendation is to have non-changed names in the fortran library
correspond to the default mode '-i4, -r4' - and mangled names for 'i8
-r8'
In addition to what I stated above, this will not work on platforms
where the default integer kind is not 4.

FX
Satish Balay
2005-02-23 22:20:20 UTC
Permalink
Post by Satish Balay
My recomendation is to have non-changed names in the fortran library
correspond to the default mode '-i4, -r4' - and mangled names for 'i8
-r8'
In addition to what I stated above, this will not work on platforms where the
default integer kind is not 4.
Well the 'unmangled' names will correspond to the 'defaults' on any
platform - so this scheme has no problem.

And the only platform I can recollect that might not default to
integer*4 are old cray machines [the current ones default to
integer*4]

Satish

Loading...