[Rd] Breaking Change in Rcomplex Layout?
Tomas Kalibera
tom@@@k@||ber@ @end|ng |rom gm@||@com
Tue Apr 4 14:48:11 CEST 2023
On 4/4/23 11:27, Michael Milton wrote:
> I don't think an auto-generated name (along the lines of u or u2) for
> the anonymous structs would be helpful here. You can see that bindgen
> is already generating a placeholder name ("__bindgen_anon_1"). A
> meaningful name might be nice instead, but I get the impression that
> isn't an option here since that would break the C API.
>
> Can I ask, would it make sense for us to hard code
> in R_LEGACY_RCOMPLEX so that Rust can just ignore the union? Because
> as I understand the only compiler that actually needs to "see" the
> union is gfortran, and if we pretend it's still a struct in Rust
> everything should work as before, no? Is this guaranteed to be a
> stable macro?
Not necessarily only gfortran, the problem arises anytime when an
Rcomplex value is (without explicit conversion) treated as C99 _Complex
double. The layout is (under some assumptions) the same, but not the
aliasing, so the information about that it can be treated as either
needs to be carried over. You would run into a similar problem when
calling say a library function expecting a C99 _Complex double, one
could argue it is not correct and one should do an explicit conversion,
but the question is how much code does it correctly. Then in theory
there could be LTO across C/Fortran/Rust and I can't rule out you
couldn't get to a similar situation (e.g. Rust calling Fortran). Ideally
really Rust should be able to translate this valid C11 code correctly.
R_LEGACY_RCOMPLEX should not be used (as the comment says), but it could
help as a temporary work-around, for cases like you are facing now.
Also, more about Rcomplex may have to change in R-devel (not for 4.3.0),
possibly requiring some API changes.
In case clarification is needed, the Fortran compiler will not see the
definition of Rcomplex at all, it will use complex numbers as defined in
Fortran, and in case of gfortran this is C99 _Complex at least on the
interface to C. The definition is for the C compiler, which compiles
code using ".r" and ".i" to access real and imaginary parts of complex
numbers. When compiling this code, the C compiler will be made aware
that values set via ".r" and ".i" may also be accessed as C99 _Complex
double objects. It will also store this information in object files, in
the intermediate representation used during link-time optimizations. The
link-time optimizer will then know that e.g. when passing Rcomplex from
(originally) C to COMPLEX*16 in (originally) Fortran, values set on the
C side via ".r" and ".i" are visible on the Fortran side in a
corresponding array of COMPLEX. Without knowing that, the link-time
optimizer could remove say stores to the ".r" and ".i" when calling to
Fortran, this is what has been actually seen to happen.
Tomas
>
> On Tue, Apr 4, 2023 at 5:50 PM Ivan Krylov <krylov.r00t using gmail.com> wrote:
>
> On Tue, 4 Apr 2023 09:31:33 +0200
> Tomas Kalibera <tomas.kalibera using gmail.com> wrote:
>
> > it also matters how Rust can handle anonymous nested structures, or
> > what is the right mapping of the involved C types to Rust
>
> It's worth mentioning that Rust's RFC 2102 [1] defines unnamed structs
> and unions for the purpose of C interoperability, but it's not yet
> implemented.
>
> Would it help Rust's bindgen (and, potentially, other C declaration
> parsers) if R could optionally give a name to the anonymous union
> member, like it's done in Windows API [2]?
>
> --
> Best regards,
> Ivan
>
> [1] https://github.com/rust-lang/rust/issues/49804
>
> [2] https://devblogs.microsoft.com/oldnewthing/20170907-00/?p=96956
>
[[alternative HTML version deleted]]
More information about the R-devel
mailing list