Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.
Announcements
The Intel sign-in experience has changed to support enhanced security controls. If you sign in, click here for more information.
27647 Discussions

Inquiry function warnings for -stand flag

andreasskeidsvoll
656 Views

Hi,

The following minimal example

program main

  use, intrinsic :: iso_c_binding, only : c_sizeof

  implicit none

  integer :: int_bit_size = bit_size(1)
  integer :: int_sizeof = sizeof(1)

  integer :: int_storage_size = storage_size(1)
  integer :: int_c_sizeof = int(c_sizeof(1))

  print *, int_bit_size, int_sizeof
  print *, int_storage_size, int_c_sizeof

end program main

 gives the following warnings during compilation

main.F90(10): warning #7347: This intrinsic function in an initialization expression is not standard Fortran 2018   [STORAGE_SIZE]
  integer :: int_storage_size = storage_size(1)
--------------------------------^
main.F90(11): warning #7347: This intrinsic function in an initialization expression is not standard Fortran 2018   [C_SIZEOF]
  integer :: int_c_sizeof = int(c_sizeof(1))
--------------------------------^

when compiled with all combinations of ifx and ifort and the flags -stand f90 -stand f95, -stand f03, -stand f08 and -stand f18. It does not give any warnings when compiled without the -stand flags.

I have had a look at the Fortran 2018 standard, and cannot see why storage_size and c_sizeof should give warnings and not bit_size. The compilers also do not give warnings for sizeof, even though it's not part of the standard. Is there something wrong with these warning messages, or am I missing something?

0 Kudos
1 Solution
Ron_Green
Moderator
534 Views

Agreed with Steve and FortranFan.  I see the bogus warning in our nightly builds as well.  We'll open a bug report.

View solution in original post

13 Replies
FortranFan
Honored Contributor II
634 Views

Correction: see the comment below:

 

TL;DR:

  • Use `C_SIZE_OF` intrinsic in executable section of the code, not in initialization expression such as "integer :: int_c_sizeof = int(c_sizeof(1))"
  • Use `C_SIZE_OF` with named objects, not literal constants.  This is because the argument X to this function has to be an interoperable entity and thus it cannot be a constant such as '1'.

Try this out and see if you would avoid the warnings with it:

 

 

   use, intrinsic :: iso_c_binding, only : c_sizeof, c_int, c_size_t
   integer(c_int), parameter :: x = 1_c_int
   integer(c_size_t) :: int_c_sizeof
   int_c_sizeof = c_sizeof(x)
   print *, "int_c_sizeof  = ", int_c_sizeof
end

 

 

 

 

 

andreasskeidsvoll
628 Views

Thank you for the response. You are right that using c_sizeof in an executable part of the code removes the warning. I would, however, like to define the integer byte size as a parameter that is reused in several parts of the code, without having to calculate it with a function each time.  You are probably also right that the c_sizeof warning might be because the argument is not a variable, although I still have to understand what it means for an entity to be interoperable.

Do you know why the warning for the storage_size function appears? There does not seem to be a requirement for interoperability in the standard, but does constants fall outside the definition of a data object? From 16.9.184 STORAGE_SIZE (A [, KIND]) in J3/18-007r1:

 

Arguments:
A    shall be a data object of any type. If it is polymorphic it shall not be an undefined pointer. If
     it is unlimited polymorphic or has any deferred type parameters, it shall not be an unallocated
     allocatable variable or a disassociated or undefined pointer.

 

 

FortranFan
Honored Contributor II
608 Views

@andreasskeidsvoll ,

Re: "I would, however, like to define the integer byte size as a parameter that is reused in several parts of the code, without having to calculate it with a function each time." - 

  • after reviewing the PDF toward the standard again on my kid's iPad in between travel points just now, apologies - I take back what I wrote earlier (I will scratch my earlier comment, I wrote too soon).  Both `C_SIZEOF` and `STORAGE_SIZE` are permitted under specification inquiry in constant expressions provided each primary is a constant expression.  So I reckon the standard permits the following (note untested) which may be what you seek:
       use, intrinsic :: iso_c_binding, only : c_sizeof, c_size_t, c_int
       integer(c_size_t), parameter :: bits_c_int = c_sizeof(1_c_int)
       integer(c_size_t), parameter :: bits_default_integer = storage_size(1, kind=c_size_t)
    end
    ​

What version of Intel Fortran are you using?  Have you tried the latest, 2023.0.0 IFX?

 

andreasskeidsvoll
582 Views

@FortranFan I'm using the 2023.0.0 ifx and 2021.8 ifort. I tried to follow your suggestion by changing the code to

 

program main

  use, intrinsic :: iso_c_binding, only : c_sizeof, c_size_t, c_int

  implicit none

  integer(c_size_t), parameter :: bits_c_int = c_sizeof(1_c_int)
  integer(c_size_t), parameter :: bits_default_integer = storage_size(1, kind=c_size_t)

  print *, bits_c_int, bits_default_integer

end program main

 

but compilation still gives the warnings

 

main.F90(7): warning #7347: This intrinsic function in an initialization expression is not standard Fortran 2018   [C_SIZEOF]
  integer(c_size_t), parameter :: bits_c_int = c_sizeof(1_c_int)
-----------------------------------------------^
main.F90(8): warning #7347: This intrinsic function in an initialization expression is not standard Fortran 2018   [STORAGE_SIZE]
  integer(c_size_t), parameter :: bits_default_integer = storage_size(1, kind=c_size_t)
---------------------------------------------------------^

 

As an additional point, I would like to use the integer bit/byte size to keep track of how much memory is used by integers in the Fortran part of the code. I would also prefer to use the default Fortran integer bit size determined by the compiler/compiler flags, without setting the integer kind in the code.

andrew_4619
Honored Contributor II
598 Views

The original code  compiles with no errors or warning using  "Intel® Fortran Compiler Classic 2021.7.0 [Intel(R) 64]"

What version are you using? I remember filing a bug report on "intrinsic function in an initialization expression" a long time ago but those got fixed.

andreasskeidsvoll
583 Views

@andrew_4619 Interesting – I'm using ifort 2021.8.0 and ifx 2023.0.0.

Steve_Lionel
Black Belt Retired Employee
553 Views

The compiler is incorrect in issuing these warnings - I agree with @FortranFan 's explanation above.

 

Ron_Green
Moderator
535 Views

Agreed with Steve and FortranFan.  I see the bogus warning in our nightly builds as well.  We'll open a bug report.

Ron_Green
Moderator
504 Views

Bug ID is CMPLRLLVM-43356


Steve_Lionel
Black Belt Retired Employee
189 Views

From the Fortran Discourse forum, the following code gives errors (not just standards warnings), where again the usage is a specification inquiry.

use,intrinsic:: ieee_arithmetic, only: ieee_support_standard
print *, [ ieee_support_standard(1e0), ieee_support_standard(1d0) ]
end program

Barbara_P_Intel
Moderator
106 Views

Thanks, @Steve_Lionel, love these short reproducers. Seems like a real constant should be acceptable. I filed a bug on this, CMPLRLLVM-43725. 

Steve_Lionel
Black Belt Retired Employee
102 Views

@Barbara_P_Intel , the problem isn't the constant, but the reference to the "specification inquiry" function - ieee_support_standard in my last post. These are allowed in constant expressions, but what qualifies as a specification inquiry isn't spelled out in the constant expression text but rather in the previous subsection on specification expressions. 

Barbara_P_Intel
Moderator
99 Views

@Steve_Lionel Thank you for the clarification! I learn a lot from reading this Forum.

Reply