Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.

Hidden character length

ereisch
New Contributor II
1,870 Views

Does the size of the hidden parameter (which is passed by value) containing the length of a string argument change with architecture?  It appears to be 4 bytes on 32-bit, but I'm having a difficult time deciphering the generated assembler to determine if it is 4 or 8 bytes on an x86_64 compilation.  The documentation that I've found is a little unclear on this.  I'm having bizarre program behavior which leads me to believe I have stack corruption.  The program is unfortunately crashing both valgrind and Intel Inspector.

0 Kudos
1 Solution
Steven_L_Intel1
Employee
1,870 Views

The string length is passed as what C would call size_t - that is indeed 8 bytes on x64.

I wouldn't expect a difference between the two calls in your example. Perhaps, rather than showing us snippets, you could provide a small but complete test case that shows the problem(s).

View solution in original post

0 Kudos
10 Replies
ereisch
New Contributor II
1,870 Views

Also, somewhat related question.  If I have some declared structure STRUCT (which may or may not be multidimensional), what is the programmatic difference between:

CALL MYFUNC( STRUCT )

and

CALL MYFUNC( %REF(STRUCT) )

?  The "MYFUNC" external is, in my practice, a C routine without a declared interface in the scope of the Fortran routine.  The generated assembly is very different between the two lines in question, in that the former appears to be performing quite a bit more operations before pushing the address onto the base pointer register.

0 Kudos
mecej4
Honored Contributor III
1,870 Views

If the number of arguments to the subroutine is small enough that the string length argument is passed in a register, it may be hard to determine whether 4 or 8 bytes are being used. If you add a few more arguments before producing the assembler code, you will see something such as 

mov       QWORD PTR [56+rsp], 5

Here, '5' is the length of the string that was passed as another argument. This should settle any doubt about the length of the length of the argument.

Unless you are interfacing Fortran and another language such as C, your program should not need to know how the string length is passed.

0 Kudos
Steven_L_Intel1
Employee
1,871 Views

The string length is passed as what C would call size_t - that is indeed 8 bytes on x64.

I wouldn't expect a difference between the two calls in your example. Perhaps, rather than showing us snippets, you could provide a small but complete test case that shows the problem(s).

0 Kudos
ereisch
New Contributor II
1,870 Views

Actually, looking back I'm realizing I never mentioned that (in the OP).  Yes, this is Fortran calling a C function.

0 Kudos
Steven_L_Intel1
Employee
1,870 Views

I'd very strongly recommend using the C interoperability features in Fortran to declare the interface to the C routine. Note that this means no hidden arguments. You can now use CHARACTER(*) in a C interface and get the length from the C descriptor passed.

0 Kudos
ereisch
New Contributor II
1,870 Views

That sounds like an option, however I hesitate a bit when I read notes about losing portability when using descriptors.  Nonetheless, I'm looking through the include folder provided with the compiler (2015.2.164, in this case), and don't see any C header files with a typedef for a descriptor field.  I realize the upper fields of the descriptors are variable based on the rank of the array, but if the lower 23 bits are fixed, and the upper bytes have structure (albeit repeating), it might be useful to include those templates in with the other definitions in this folder.

Also, I noticed while I was browsing this folder that, at least in my installed version, omp_lib.h appears to actually be a F90 file, rather than a C header (and oddly enough, different than omp_lib.f90).

As for the differences in passing implicitly via reference and using the %REF tag, I'll work on creating a reproducer and upload it as soon as I get a chance.

 

Thanks

0 Kudos
Steven_L_Intel1
Employee
1,870 Views

C descriptors are a Fortran 2015 feature and were new in the Intel "2016" product.  Yes, omp_lib.h is a Fortran file - there are a lot of Fortran include files with .h file types (not our choice - this comes from the MPI committee.) And yes,omp_lib.f90 is different (it's a module).

0 Kudos
ereisch
New Contributor II
1,870 Views

If I were to convert *all* of my C routine calls from Fortran to have interface definitions, I'd have to account for a couple (C-routines) which are actually variadic functions.  This isn't an issue for us at the moment with implicit declarations of external subroutines, since Fortran just pushes the pointers to the arguments onto the stack, and then the C routine pulls the appropriate number of arguments back off based on the content.  The documentation doesn't seem to suggest there's a way to properly prototype a C variadic function in Fortran.  Should I just leave these functions as the old method (i.e. "pretending" we are Fortran on the other side by catching and pulling off hidden character size variables), or is there a smarter way to accomplish this?

0 Kudos
jimdempseyatthecove
Honored Contributor III
1,870 Views

If by C you (could) mean C++ with variadic templates, then you could define a template that constructs a NULL terminated variable length struct containing values and/or references of your design. Then pass the reference to this struct for processing by your Fortran routine.

Jim Dempsey

0 Kudos
JVanB
Valued Contributor II
1,870 Views

See what you can do with !DEC$ ATTRIBUTES VARYING

 

0 Kudos
Reply