- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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...
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Strangely, the input form corrupts my Fortran code: line 7 should read " if (c_sizeof (b) /= 8 )
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
@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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Well, that is now confusing. There's talk about "Interoperability of intrinsic types" and "Interoperability of scalar variables". So what is the latter?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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 )
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
@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.)
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
@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
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page