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

Interoperability of character variables

Harald1
Novice
623 Views

The code

 

 

program main
  use, intrinsic :: iso_c_binding
  implicit none
  character(kind=c_char, len=*), parameter :: a = 'abc'
  character(kind=c_char, len=8)            :: b
  if (c_sizeof (a) /= 3) stop 1
  if (c_sizeof (b) /=  stop 2
end program main

is rejected by Intel 2021.4.0:

 

c_sizeof_7.f90(7): error #8950: A character data entity with length other than 1 is not interoperable.   [B]
  if (c_sizeof (b) /=  stop 2
----------------^
compilation aborted for c_sizeof_7.f90 (code 1)

 

Note that the named constant a is accepted, only variable b is rejected.

 

F2008:15.3.5 Interoperability of scalar variables
has relaxed the condition on the length to be one.  Looks like a forgotten update in the compiler.

Thanks,

Harald

 

0 Kudos
10 Replies
andrew_4619
Honored Contributor II
613 Views

For what it is worth I would have thought both should be rejected as c_sizeof only accepts interoperable objects which for character is arrays of 1 character length. 

Steve_Lionel
Black Belt Retired Employee
602 Views

I'm not sure what @Harald1 is referring to regarding "relaxing", as I don't see any changes there. As @andrew_4619 correctly points out, the argument to C_SIZEOF is required to be interoperable and neither a nor b are such. The only context where these could appear in an interoperable fashion is as the actual argument to a procedure declared with BIND(C). In F2008, this would be restricted to a dummy argument declared as a rank-1 array of character(1).  In F2018, the dummy argument could be character(*), corresponding to a "C descriptor" in the called procedure.

The compiler should have complained about both calls to C_SIZEOF.

Harald1
Novice
590 Views

Steve,

for one thing, nvfortran and flang accept the code.

Can you explain the relevant standard text to me?  I am probably too confused.

 

F2018: 18.2.3.7 C_SIZEOF (X)

Argument. X shall be an interoperable data entity ...

 

F2018: 18.3.4 Interoperability of scalar variables
A named scalar Fortran variable is interoperable if and only if its type and type parameters are interoperable, [...], and if it is of type character
its length is not assumed or declared by an expression that is not a constant expression.

 

Note: it does not say length one.

 

F2003: 15.2.1Interoperability of intrinsic types
[...] A Fortran intrinsic type with particular type parameter values is interoperable with a C type if the type and kind type
parameter value are listed in the table on the same row as that C type; if the type is character, inter-
operability also requires that the length type parameter be omitted or be specified by an initialization
expression whose value is one.

 

I'd say that this is different.

 

Caveat: I'm neither a native speaker nor a Fortran standard legalese expert...

 

Harald1
Novice
588 Views

Strangely, the input form corrupts my Fortran code: line 7 should read " if (c_sizeof (b) /= 8 ) stop 2" but the "8)" part gets deleted.  Fortran doesn't support any kind of smileys, does it?

 

Steve_Lionel
Black Belt Retired Employee
580 Views

@Harald1 , I am going to quote from Fortran 2018 (emphasis mine), though the 2008 text (15.3.2p1) is the same:

18.3.1p1 Interoperability of intrinsic types

Table 18.2 shows the interoperability between Fortran intrinsic types and C types. A Fortran intrinsic type with particular type parameter values is interoperable with a C type if the type and kind type parameter value are listed in the table on the same row as that C type. If the type is character, the length type parameter is interoperable if and only if its value is one.

Harald1
Novice
575 Views

Well, that is now confusing.  There's talk about "Interoperability of intrinsic types" and "Interoperability of scalar variables".  So what is the latter?

andrew_4619
Honored Contributor II
558 Views

It is of type character which is listed as a special case. Anyway why use C_SIZEOF( a ) when character has its very own size function called LEN( a )

Harald1
Novice
568 Views

And while we're at it: if a processor has different character kinds, in principle any of those which has a representation using one byte could be interoperable with C.  (I'm not talking about the opposite direction and the signedness discussion in 18.3.1 Note 1.)

And how shall I read the "interoperable data entity" referred to in the definition of C_SIZEOF?

 

Steve_Lionel
Black Belt Retired Employee
540 Views

@Harald1 wrote:

And while we're at it: if a processor has different character kinds, in principle any of those which has a representation using one byte could be interoperable with C.  (I'm not talking about the opposite direction and the signedness discussion in 18.3.1 Note 1.)

And how shall I read the "interoperable data entity" referred to in the definition of C_SIZEOF?

 


The standard says that the character kind interoperable with C char is, if it exists, C_CHAR. This may or may not be the same as "default character kind".

The term "interoperable" is used in different contexts, and can refer to types, variables, procedures and globals. The section about interoperable variables means variables which are the same as the appropriately declared variable in C. In the case of C_SIZEOF, there are two terms you need to understand, "interoperable" and "data entity". Both have definitions in the Terms and Definitions clause. "data entity" is "data object, result of the evaluation of an expression, or the result of the execution of a function reference", and "data object" has its own definition of "constant (7.1.4), variable (9), or subobject of a constant (5.4.3.2.4)". So here, it means you can't ask the C_SIZEOF of an interoperable procedure or type. "interoperable", in the broader sense used here, is defined as "⟨Fortran entity⟩ equivalent to an entity defined by or definable by the companion processor (18.3)"

Both constants and variables are data entities that could be interoperable. Constants are interoperable if their type is interoperable. Variables have some additional constraints (can't be ALLOCATABLE or a coarray, for example.)

FortranFan
Honored Contributor II
559 Views

@Harald1 ,

 

Note section 18.3.1 Interoperability of intrinsic types in 18-007r1 document toward the Fortran standard states, "If the type is character, the length type parameter is interoperable if and only if its value is one."

To make a long story short re: your questions, the following should be acceptable per the standard but what you show in the original post does not conform with the standard.

   use, intrinsic :: iso_c_binding
   character(kind=c_char, len=1), parameter :: a(*) = [ 'a', 'b', 'c' ]
   character(kind=c_char, len=1) :: b(8)
   print *, "c_sizeof(a) = ", c_sizeof(a)
   print *, "c_sizeof(b) = ", c_sizeof(b)
end
Reply