iso_C_binding c_sizeof

iso_C_binding c_sizeof

A quick question is the f2008 iso_C_binding  c_sizeof implemented in the latest release (an am not as yet using this) and if not when could we expect this to be implemented? It isn't an issue, more a point of interest.

13 posts / 0 new
Last post
For more complete information about compiler optimizations, see our Optimization Notice.

Yes, we support c_sizeof in the current release.

Steve - Intel Developer Support

Thanks for the info Steve.

Perhaps it was supported in the version I already had installed. I assumed is wasn't supported because it wasn't in the help. But it isn't in the help in XE 14.0.1.139 either as I just installed it.

It does appear to work though! Am I correct in assuming that C_sizeof behaved EXACTLY like sizeof and also is a 4 or 8 byte result depending on the platform x32/x64?

Perhaps the help needs updating (it is listed as a procedure under the ISO_C_BINDING topic but that is  full extent, there is no topic or index entry.

Yep - we missed adding this to the help. By the way, the release notes list all of the F2003/F2008 features supported.

Yes, C_SIZEOF returns a size that is 32 or 64 bits depending on platform, but it is not exactly like SIZEOF in that the latter can be used in constant (initialization) expressions but C_SIZEOF cannot. Otherwise they are the same.

Steve - Intel Developer Support

Why the standard does now allow using sizeof ( or c_sizeof ) in the initialization expressions is beyond my capability of comprehension. Can anyone give me some rationale, so that I can get over it ?
And, what is the suggested replacement for that , if any ?

Thanks in advance.

The workaround is to fix the compiler. Consider:

program p
   use ISO_C_BINDING
   implicit none
   logical(C_BOOL) x(KIND(1.0))
   integer, parameter :: s = SIZEOF(x)
   real(s) y
   y = 1.0
   write(*,*) y
end program p

Compiles fine with /stand with output 1.000000, but

program p
   use ISO_C_BINDING
   implicit none
   logical(C_BOOL) x(KIND(1.0))
   integer, parameter :: s = C_SIZEOF(x)
   real(s) y
   y = 1.0
   write(*,*) y
end program p

fails to compile. In section 7.1.11 of a recent standard we see:

A specification inquiry is a reference to
...
(4) the function C SIZEOF from the intrinsic module ISO C BINDING (15.2.3.7), or ..

And then in section 7.1.12

A constant expression is an expression with limitations that make it suitable for use as a kind type parameter,
initializer, or named constant. It is an expression in which each operation is intrinsic, and each primary is
...
(4) a specification inquiry where each designator or function argument is
...
(b) a variable whose properties inquired about are not
(i) assumed,
(ii) deferred, or
(iii) defined by an expression that is not a constant expression, ...

But in Intel's docs, neither SIZEOF nor C_SIZEOF is listed among the allowed functions in a specification inquiry allowed in a specification expression, although SIZEOF is listed as one of the functions allowed in a specification inquiry. Also a bunch of transformational functions are not listed as allowed in constant expressions although they have all been allowed by the standard since f03. I haven't tested whether this nonconformance for transformational intrinsics resides in the compiler or only the documentation.

 

I tried testing some transformational intrinsics and found that support for them in constant expressions is spotty at best. For example, ifort considers TRANSFER(1,0) to be a constant expression but not TRANSFER([1],0), which even f95 allows (with diglyphs). Since this syntax and sum([1]) are not allowed, I can't see how to nondestructively test transformational intrinsics which return arrays. My test even caused an ICE with COMMAND_ARGUMENT_COUNT:

      function COMMAND_ARGUMENT_COUNT_test() bind(C)
         use ISO_C_BINDING
         implicit none
         logical(C_BOOL) COMMAND_ARGUMENT_COUNT_test
         character(len=COMMAND_ARGUMENT_COUNT()*0+1),allocatable :: C
         save
         if(allocated(C)) then
            COMMAND_ARGUMENT_COUNT_test = .TRUE._C_BOOL
         else
            COMMAND_ARGUMENT_COUNT_test = .FALSE._C_BOOL
            allocate(C)
         end if
      end function COMMAND_ARGUMENT_COUNT_test

ifort /c CAC.f90 fails with ICE, even with version 15.0.1.148, which is hard to get with MSIE 11, but it turns out that if you go through Start > Intel Parallel Studio XE 2015 > Intel Software Manager, the download button works from there.

 

OK, I found an array reduction that works sometimes. One that causes another failure, however, is:

      function CSHIFT_test() bind(C)
         use ISO_C_BINDING
         implicit none
         logical(C_BOOL) CSHIFT_test
         type Q
            integer,allocatable :: x(:)
         end type Q
         character(len=TRANSFER(Q(CSHIFT([1],1)),0)*0+1),allocatable :: C
         save
         if(allocated(C)) then
            CSHIFT_test = .TRUE._C_BOOL
         else
            CSHIFT_test = .FALSE._C_BOOL
            allocate(C)
         end if
      end function CSHIFT_test

ifort /c CS.f90 yields the following error:

CS.f90(8): error #6273: In a constant expression, the only value that may corres
pond to an allocatable component is a reference to NULL().
         character(len=TRANSFER(Q(CSHIFT([1],1)),0)*0+1),allocatable :: C
----------------------------------^
compilation aborted for CS.f90 (code 1)

but this is wrong because LEN(C) need not be given by a constant expression, so the function should compile.

 

Quote:

e745200 wrote:

Why the standard does now allow using sizeof ( or c_sizeof ) in the initialization expressions is beyond my capability of comprehension. Can anyone give me some rationale, so that I can get over it ?
And, what is the suggested replacement for that , if any ?

Thanks in advance.

Not sure I understand your question: did you mean, "Why the standard does not allow using c_sizeof"?  Because if so, that is not correct - the standard does indeed allow C_SIZEOF in initialization expressions (but with certain restrictions of course as explained in section 7.1 and 7.2 of the standard).  It is just that this feature has not yet been implemented in Intel Fortran yet.  Now isn't SIZEOF an Intel Fortran extension, hence it will outside the scope and the standard will make no reference to it.

I'm about halfway through the list of transformational intrinsics, but I'm hung up on NULL.

program P
   implicit none
   type T
      integer, pointer :: x(:)
   end type T
   type(T), parameter :: J = T(NULL())
   write(*,*) ASSOCIATED(NULL(J%x))
end program P

ifort says

NL.f90(7): error #7029: Invalid context for  NULL(...).   [NULL]
   write(*,*) ASSOCIATED(NULL(J%x))
-------------------------^
compilation aborted for NL.f90 (code 1)

and gfortran says

NL.f90:6.31:

   type(T), parameter :: J = T(NULL())
                               1
Error: 'mold' argument of 'null' intrinsic at (1) must be a variable

But I don't get it... my code looks OK to me.

 

Well, I made it through the list of transformational intrinsics. I couldn't get COMMAND_ARGUMENT_COUNT, FINDLOC, NULL(MOLD), or IEEE_SELECTED_REAL_KIND to compile and THIS_IMAGE silently failed at runtime, but for the others I got:

Transformational procedure ALL is NOT usable in constant expressions
Transformational procedure ANY is NOT usable in constant expressions
Transformational procedure COUNT is NOT usable in constant expressions
Transformational procedure CSHIFT is NOT usable in constant expressions
Transformational procedure DOT_PRODUCT is NOT usable in constant expressions
Transformational procedure EOSHIFT is NOT usable in constant expressions
Transformational procedure IALL is usable in constant expressions
Transformational procedure IANY is usable in constant expressions
Transformational procedure IPARITY is usable in constant expressions
Transformational procedure MATMUL is NOT usable in constant expressions
Transformational procedure MAXLOC is NOT usable in constant expressions
Transformational procedure MAXVAL is usable in constant expressions
Transformational procedure MINLOC is NOT usable in constant expressions
Transformational procedure MINVAL is usable in constant expressions
Transformational procedure NORM2 is usable in constant expressions
Transformational procedure NUM_IMAGES is NOT usable in constant expressions
Transformational procedure PACK is NOT usable in constant expressions
Transformational procedure PARITY is NOT usable in constant expressions
Transformational procedure PRODUCT is NOT usable in constant expressions
Transformational procedure REPEAT is usable in constant expressions
Transformational procedure RESHAPE is usable in constant expressions
Transformational procedure SELECTED_CHAR_KIND is usable in constant expressions
Transformational procedure SELECTED_INT_KIND is usable in constant expressions
Transformational procedure SELECTED_REAL_KIND is usable in constant expressions
Transformational procedure SPREAD is NOT usable in constant expressions
Transformational procedure SUM is NOT usable in constant expressions
Transformational procedure TRANSFER(SCALAR) is usable in constant expressions
Transformational procedure TRANSFER(VECTOR) is NOT usable in constant expressions
Transformational procedure TRANSPOSE is NOT usable in constant expressions
Transformational procedure TRIM is usable in constant expressions
Transformational procedure UNPACK is NOT usable in constant expressions

I will attempt to attach the program

Attachments: 

AttachmentSize
Download trans.f9016.87 KB

We're aware of the inability to use C_SIZEOF in constant expressions. Use the extension SIZEOF as a replacement for now.

RO, your list of transformational intrinsics includes some from F2008 and some, such as NUM_IMAGES, that F2008 doesn't allow in constant expressions. We know of only a few intrinsics missing from our F2003 support of initialization expressions, including those from intrinsic modules.

I'll have to study your program in more detail, but I know that many of the procedures it says are "not supported" are in fact supported in constant expressions. Your program may be revealing other issues, however.

Steve - Intel Developer Support

I just searched a draft of the standards document for the string 'Class. Transformational' and tested the 35 hits that I got. My test program sets the LEN of a CHARACTER variable with the ALLOCATABLE attribute using the tested transformational intrinsic. If the compiler considers the resulting expression for the LEN to be an initialization expression, it applies the blanket SAVE to the ALLOCATABLE CHARACTER variable with the result that it will be allocated on the second invocation of the test function. If the expression for the LEN is not considered to be an initialization expression, the CHARACTER variable is an automatic data object so the blanket SAVE does not apply to it and it will not be allocated the second time around.

Thus, even if the transformational intrinsic is not allowed by the compiler or even the standard to be used in initialization expressions, the test function should still compile and run without crashing, so I consider the 5 instances outlined in quote #11 and removed from trans.f90 with !DEC$ IF(.FALSE.) to be bugs. Obviously there are some intrinsics that can't be used in initialization expressions, such as COMMAND_ARGUMENT_COUNT, but they should still compile and run.

The object of the exercise was to determine transformational intrinsics that ifort supports. I note the ifort docs call out the transformational intrinsics REPEAT, RESHAPE, SELECTED_CHAR_KIND, SELECTED_INT_KIND, SELECTED_REAL_KIND, TRANSFER, TRIM, and NULL as being supported in initialization expressions, and indeed my program detects all of these (while putting an asterisk on TRANSFER)  and in addition detects the undocumented support of IALL, IANY, IPARITY, MAXVAL, MINVAL, and NORM2 (why isn't NORM2 allowed for COMPLEX inputs in the standard?). Are there some additional transformational intrinsics supported in initialization expressions that my program isn't detecting? If you can think of some, please let me know so that I can write another test for them.

Well, I guess my program failed on NULL, but I think that is a problem with the compilers (quote #10) although I'm not completely certain about the correctness of my code in this instance because I've never used NULL with the MOLD argument before.

 

Leave a Comment

Please sign in to add a comment. Not a member? Join today