Home > Archive > Fortran > February 2007 > Variable number of arguments
You are viewing an archived Text-only version of the thread.
To view this thread in it's original format and/or if you want to reply to
this thread please [click here]
| Author |
Variable number of arguments
|
|
| salgerman@gmail.com 2007-02-22, 7:08 pm |
| I have about 100 fortran-77 programs that I need to enhance in a
certain way. To accomplish such task, I thought implementing a C
function with variable number of arguments would allow me to do what I
need.
I have implemented the entire functionality and it works in MinGW and
in Solaris, but it does not work in Linux, and I do need it to work
there, too!
As I started to take commands out for debugging purposes, I ended up
discovering that it is just not letting me do "variable number of
arguments" in the first place...but just Linux! Otherwise this
minimal program and my full version they both work just fine in MinGW
and Solaris.
%%%%%%%%%%%%%%%%%%%%%%%%%%%
Here are my platforms
My Dell D600 Windows XP with MinGW "Intel-inside" Box.
MINGW32_NT-5.1 W72C-CGFJN41 1.0.11(0.46/3/2) 2004-04-30 18:55
i686 unknown
My Solaris sparc Box:
SunOS pillbox 5.9 Generic_118558-24 sun4u sparc SUNW,Sun-
Blade-1500
My Red Hat Linux AMD Box:
Linux egret 2.6.9-42.0.3.ELsmp #1 SMP Mon Sep 25 17:24:31 EDT
2006 x86_64 x86_64 x86_64 GNU/Linux
%%%%%%%%%%%%%%%%%%%%%%%%%%%
// Here is my C function with variable number of arguments: prog.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>
//void c_function(const char *fmt) // this works
void c_function(const char *fmt,...) // this does not
{
printf("Inside c_function, fmt = %s\n", fmt);
return;
}
%%%%%%%%%%%%%%%%%%%%%%%%%%%
c Here is my fortran 77 program calling the C function: test.f
program main
character nl
nl = char(0)
call c_function('The %s is '//nl)
end
%%%%%%%%%%%%%%%%%%%%%%%%%%%
Here is how I compile:
gcc -c prog.c
g95 -c -fno-underscoring test.f
g95 -o test test.o prog.o
Does anybody have any idea what the problem could be? and its
solution?
Thanks in advance for any pointers.
gsal
| |
| Richard Maine 2007-02-22, 7:08 pm |
| <salgerman@gmail.com> wrote:
[much elided]
> //void c_function(const char *fmt) // this works
> void c_function(const char *fmt,...) // this does not
....
> call c_function('The %s is '//nl)
Calling C from Fortran is full of portability issues. It can be done,
but there are lots of gotchas. That's why the C interop stuff is one of
the major features of f2003.
You are apparently aware of at least one aspect of the name mangling
issue. Your use of the -fno-underscoring option shows that. Be aware
that that issue has lots of variants and isn't always so easily solved.
Also, using -fno-underscoring can cause problems elsewhere because all
the code in a program needs to be compiled with that option the same
way, which is problematic if, for example, you are using 3rd party
libraries. Basically, that switch is the simplest way to avoid the
problem in some cases, but it is not a very robust way.
But your current problem is probably different. Fortran character
arguments have extra data associated with them. As long as you are just
in Fortran, that is taken care of "behind your back". When you try to
mix languages, it is visible and must be accounted for. The details *DO*
vary from compiler to compiler.
The most common scheme is to pass the address of the string as one
argument and the length in a separate argument, which the compiler
constructs for you. That extra argument is usually the length passed by
value. Sometimes the extra argument is added right after the address
one. Sometimes it is added way at the end of the list of arguments.
--
Richard Maine | Good judgement comes from experience;
email: last name at domain . net | experience comes from bad judgement.
domain: summertriangle | -- Mark Twain
| |
| salgerman@gmail.com 2007-02-22, 7:08 pm |
| Yes, I am aware of all those issues; except, maybe, about the one
where the length of a string may come right after the string, as
opposed to all the way to the end of all declared arguments.
In any case, I have been cruising just fine as I have ported about
dozen libraries and getting ready to port about 100 programs; I do
have other C libraries being called from fortran and they all work.
So, -fno-underscoring is working so far within all my in-house
code...I would eventually have to link against a couple of 3rd party
libraries, though, so, thanks from bringing that to my attention.
Sure, C-fortran interoperability may have some gotchas, and that's
what I was trying to minimize, too, by using the same compiler in all
3 platforms.
As mentioned before, this same program works fine in MinGW and
Solaris, but not in Linux...with g95, anyway. I just tried with
Absoft compiler in Linux, and it worked, too....so, yes, things vary
from compiler to compiler, and from platform to platform with the same
compiler, as in my case...maybe is a library problem?
thanks
gsal
| |
| salgerman@gmail.com 2007-02-22, 10:06 pm |
| Well...never mind about this issue, and sorry. The thing is this
programs compiles and run in the other two platforms and it compiles
and runs in Linux with a couple other fortan compilar I have access to
(Absoft and Portland)...so, I don't know if this is a shortcoming of
g95 in Linux or just the installation.
gsal
| |
| Richard Maine 2007-02-22, 10:06 pm |
| <salgerman@gmail.com> wrote:
> Well...never mind about this issue, and sorry. The thing is this
> programs compiles and run in the other two platforms and it compiles
> and runs in Linux with a couple other fortan compilar I have access to
> (Absoft and Portland)...so, I don't know if this is a shortcoming of
> g95 in Linux or just the installation.
I thought I answered that. As I mentioned before, different compilers do
it differently. So verifying that it works on some compilers doesn't
mean that it will work on others. It is a function of teh compiler - not
the operating system. It isn't a matter of a shortcoming, as there is no
standard for this. Have you checked into the issue I mentioned about the
position of the extra length argument for characters? That's sure what
it sounds like. It wasn't obvious to me that you had checked into that.
Note also that on some systems, you can't get by with just ignoring
extra arguments in C, even if they are on the end. It messes up the
stack or some such thing. I recall having problems with that on some Sun
systems. You actually have to have the arguments agree, even if you end
up not using some of them.
--
Richard Maine | Good judgement comes from experience;
email: last name at domain . net | experience comes from bad judgement.
domain: summertriangle | -- Mark Twain
| |
| salgerman@gmail.com 2007-02-22, 10:06 pm |
| Yes,you are right about different compiler behaving differently...the
thing that keeps throwing me off is the fact that I am using the same
compiler (g95) in all three platforms...so you would think...
Anyway, as far as the length of the string goes, that issue is not
bothering when the program works, in other words, when I run my full
version program and pop arguments out of the stack, I do get the
arguments, not the length of the format string.
The minimalistic program that I included above fails as soon as you
include the elipsis (...) in the function declaration, even without
actually including extra arguments in the call to it...as simple as
that.
Anyway, thanks for keeping up...I'm bummed (sp?), but I think we need
to wrap this problem up and leave it unresolved like this...as far as
my g95 instance...I may just use Absoft in Linux.
thanks.
gsal
| |
| glen herrmannsfeldt 2007-02-22, 10:06 pm |
| salgerman@gmail.com wrote:
(snip)
> // Here is my C function with variable number of arguments: prog.c
> #include <stdio.h>
> #include <stdlib.h>
> #include <string.h>
> #include <stdarg.h>
> //void c_function(const char *fmt) // this works
> void c_function(const char *fmt,...) // this does not
> {
> printf("Inside c_function, fmt = %s\n", fmt);
> return;
> }
In K&R C there is no special declaration for functions with a variable
number of arguments, the ... above. ANSI added that, and allows such
functions to use a different and incompatible calling method for those
functions. C doesn't provide any way for the called routine to
find out how many arguments are really there, so that on machines that
pass arguments on a stack, the calling routine must pop the stack
(at least for varargs routines).
The x86 processors supply a convenient way for a called routine to
pop arguments off the stack, and some systems (including most early
DOS Fortran and Pascal compilers) used that, but it only works if the
number of arguments is fixed. Many have now changed to the C calling
convention, though.
The calling convention is usually documented. Otherwise you can compile
different programs with the option to show the generated assembly code
(-S on most unix-like systems) and look at the generated code.
-- glen
| |
| glen herrmannsfeldt 2007-02-23, 4:15 am |
| Richard Maine wrote:
(snip)
> But your current problem is probably different. Fortran character
> arguments have extra data associated with them. As long as you are just
> in Fortran, that is taken care of "behind your back". When you try to
> mix languages, it is visible and must be accounted for. The details *DO*
> vary from compiler to compiler.
> The most common scheme is to pass the address of the string as one
> argument and the length in a separate argument, which the compiler
> constructs for you. That extra argument is usually the length passed by
> value. Sometimes the extra argument is added right after the address
> one. Sometimes it is added way at the end of the list of arguments.
I believe there are also some, I believe VMS being one, that pass the
address of a descriptor containing the address of the string and the
length. That is part of the VMS system standard for calling conventions.
But C normally provides no way for the called routine to know how
many arguments there are. It must be somehow coded in the parameters,
such as the number of format descriptors in the first argument to
printf. It would be usual, though not required by the standard,
for a one argument call to work even with ... in the arglist.
-- glen
| |
| glen herrmannsfeldt 2007-02-23, 4:15 am |
| Richard Maine wrote:
> Note also that on some systems, you can't get by with just ignoring
> extra arguments in C, even if they are on the end. It messes up the
> stack or some such thing. I recall having problems with that on some Sun
> systems. You actually have to have the arguments agree, even if you end
> up not using some of them.
The ... is C's indication for a variable number of arguments.
One would have to read the C rules carefully for that case, but
I believe if you have declared it that way it has to work even if
you don't use all of them.
-- glen
| |
| Jan Vorbrüggen 2007-02-23, 4:15 am |
| > Yes,you are right about different compiler behaving differently...the
> thing that keeps throwing me off is the fact that I am using the same
> compiler (g95) in all three platforms...so you would think...
Even if it's the same compiler, it will usually conform to (one of) the ABIs
(application binary interfaces) - aka "calling conventions" - of the platform
you are using. Windows happens to have several of these ABIs, and I don't know
offhand which g95 is using. The Intel compiler, for instance, allows you to
choose at various granularity which ABI you might want to use.
So the fact that your C and your Fortran compiler interoperate on one
platform, and the same compilers do not do so on another platform, is entirely
to be expected 8-|.
Jan
| |
| Pierre Asselin 2007-02-23, 7:10 pm |
| glen herrmannsfeldt <gah@ugcs.caltech.edu> wrote:
> salgerman@gmail.com wrote:
> (snip)
[color=darkred]
> In K&R C there is no special declaration for functions with a variable
> number of arguments, the ... above. ANSI added that, and allows such
> functions to use a different and incompatible calling method for those
> functions.
What ANSI added is a way to *write* variadic functions in C. In
K&R C you could always call functions like printf() with varying
argument lists, but printf() itself could not be written portably
in C. What is still missing is a way to synthesize a an argument
list at run-time.
To the OP: *don't* try to call variadic C functions from Fortran.
Give up now.
--
pa at panix dot com
| |
| Colin Watters 2007-02-24, 7:04 pm |
|
<salgerman@gmail.com> wrote in message
news:1172160672.217867.138430@l53g2000cwa.googlegroups.com...
> I have about 100 fortran-77 programs that I need to enhance in a
> certain way. To accomplish such task, I thought implementing a C
> function with variable number of arguments would allow me to do what I
> need.
....It might be a great deal easier to impliment a Fortran-95 function or
subroutine with a number of optional arguments. That would avoid all the
language interop stuff that others have discussed.
> --
Qolin
Email: my qname at domain
Domain: qomputing dot demon dot co dot uk
|
|
|
|
|