use iso_c_binding
type, bind(c) :: t1
integer :: i(5)
end type t1
type, bind(c):: t2
type(t1) :: t(5)
end type t2
type(t2), target :: tt
type(C_PTR) :: p
p = c_loc(tt%t%i(1))
end
Personally, I think it is invalid. 15.1.2.5, in the description of
C_LOC, allows for the argument that has the TARGET attribute (which
it has) and which is interoperable. As far as interoperable variables
go, I don't think that tt%t%i(1) is an array variable.
Is this analysis correct?
Taking the i component as having c_int kind, tt%t%i(1) is an
array-section (R617 - the %t part has a rank of one). An array-section
is an array (6.2.2), but it's not an explicit shape or assumed size
array, so therefore it is not an interoperable array variable (15.2.5).
So it doesn't meet any of the criteria for the argument of C_LOC in F2003.
In F2008 terms, tt%t%i(1) is not contiguous - same outcome.
I agree with your conclusion that the code is invalid, but I frankly
don't understand what your analysis even means, so I can't agree with
it.
tt%t%i(1) is an array variable. I don't know of any concept of being an
array variable "as far as interoperable variables go."
Now there are restrictions that must be met for an array variable to be
interoperable. Perhaps you are talking about those restrictions. But if
something fails to meet those restrictions, I certainly would not
describe it as not being an array variable "as far as interoperable
variables go". I would just say that it is not interoperable because it
fails to meet the requirements of interoperability for array variables.
The particular restriction I have in mind for this case is one that I
think is poorly worded (at least in f2003; I didn't check to see whether
f2008 improves on this). Namely, in the first sentence of 15.2.5, we see
that an interoperable array variable must be "of explicit shape or
assumed size". That wording sounds to me an awful lot like someone who
was still in the f77 mode of thinking that "variable" always means the
whole of some declared thing. In f77, if x is an array, then x(1) is not
a variable; it is an array element, which is a separate category of
thing all on its own. (For that matter, an array in f77 isn't a variable
either; it is an array, which is also a separate category). As of f90, a
subobject of a variable is also a variable.
It is at best confusing to talk about a requirement that an array
variable be explicit shape or assumed size because those concepts apply
only to arrays that have declarations. Array slices never have
declarations for the question to come up. Putting on my language-lawyer
hat, I'd probably say that this means an array slice can never be
interoperable. (The variable in question here is an array slice). It
also turns out that it makes sense to me that an array slice would not
be interoperable; I just think that the standard could have worded this
a lot better, perhaps saying something explicit about slices instead of
letting one deduce that the concepst didn't apply to slices, so maybe
they don't work.
The reason it makes sense to me that array slices would not be
interoperable is that an array slice might be noncontiguous. C interop
doesn't deal with non-contiguous things (except sometimes by implying a
contiguous copy). Some array slices might happen to be contiguous, but I
can see it as being sensible to just disallow them all instead of trying
to say that a slice is ok as long as it happens to be contiguous (and
then get into questions about wehther it has to be known at compile time
to be contiguous). Your particular slice, by the way, would not be
contiguous.
--
Richard Maine | Good judgment comes from experience;
email: last name at domain . net | experience comes from bad judgment.
domain: summertriangle | -- Mark Twain
> The particular restriction I have in mind for this case is one that I
> think is poorly worded ... Namely, in the first sentence of 15.2.5, we see
> that an interoperable array variable must be "of explicit shape or
> assumed size"....I just think that the standard could have worded this
> a lot better, perhaps saying something explicit about slices instead of
> letting one deduce that the concepst didn't apply to slices,
Writing that made me curious whether a "certain book," which alleges to
help with understanding the standard, might have done better on this. I
don't off-hand recall whether we got this one. Let's see... Yep. (Makes
me feel better).
Pg 568 of the f2003 Handbook, second para of 15.5.2
"The requirement for explicit shape or asumed size rules out
assumed-shape and deferred-shape arrays, plus all array sections. This
requirement ensures contiguity in memory, as required by C....."
> Pg 568 of the f2003 Handbook, second para of 15.5.2
>
> "The requirement for explicit shape or asumed size rules out
> assumed-shape and deferred-shape arrays, plus all array sections. This
> requirement ensures contiguity in memory, as required by C....."
Thanks a lot! It hadn't occurred to me to check the F2003 Handbook as well as
the standard.
This will make error checking (and error messages) much easier.
> Pg 568 of the f2003 Handbook, second para of 15.5.2
>
> "The requirement for explicit shape or asumed size rules out
> assumed-shape and deferred-shape arrays, plus all array sections. This
> requirement ensures contiguity in memory, as required by C....."
There's currently a debate on the gfortran mailing list on this,
see http://gcc.gnu.org/ml/fortran/2011-01/msg00103.html .
The question there is if
use iso_c_binding
integer(c_int), target :: n(3)
type(C_PTR) :: p
p = c_loc(n(1:2)) ! { dg-error "Array section not permitted" }
end
is legal or not. There might also be a difference between F 2003 and
F2008 in this respect.
(My personal opinion is that Richard's arguments apply as well, but as I
am not sure, I'd like to ask :-)
As written at fortran@gcc I believe it is valid according to the current
Fortran standard as "n(1:2)" is contiguous; actually it is even simply
contiguous (i.e. the compiler can know at compile-time the variable is
contiguous).
"15.2.3.6 C LOC (X)" [...]
"Argument. X shall have either the POINTER or TARGET attribute. It shall
not be a coindexed object. It shall either be a variable with
interoperable type and kind type parameters, or be a scalar,
nonpolymorphic variable with no length type parameters. If it is
allocatable, it shall be allocated. If it is a pointer, it shall be
associated. If it is an array, it shall be contiguous and have nonzero
size. It shall not be a zero-length string."
The term contiguous is defined in 5.3.7 while simply contiguous is
defined in 6.5.4.
Tobias
I believe it is invalid in f2003, for the reasons cited. Look through
the conditions listed in c_loc, and it meets none of them. The "closest"
is "a variabel that has the TARGET attribute and is interoperable", but
as noted, this variable is a section, which is not interoperable. The
compiler is not required to diagnose this error and thus could quietly
accept it as an extension.
I've not studied f2008 adequately to answer for it. The argument that
Tobias gives sounds persuasive, but I haven't checked all the references
sufficiently to say that I affirm it.