[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