Sun 17 Jul 2016 11:58:24 AM UTC, comment #4:
>>
Does putting a function signature in an extern "C" block somehow allow
the compiler to treat a std::complex<T> argument as a C complex argument?
>>
No, the reinterpret_cast<>() does that.
I don't claim to be a standards expert. This is my understanding of the situation and I'd be happy to be set straight. From the C++ standard Section 26.5 Complex numbers:
std::complex<float> is not a simple data type (POD) but it is a composition of two POD data (struct-POD). The reinterpret_cast<> ensures that the pointer passed to the Fortran side is actually a pointer to the internal data not to the C++ class instance. I'd be disappointed if the compiler designers had made std::complex<float> * not point at the underlying data but apparently this is not guaranteed.
The gfortran Fortran side expects to see a C language array of float _complex_. The iso_c_binding c_float_complex would enforce this but gfortran doesn't need it. I tried changing the function signature in schur.cc to:
The warning messages returned.
As you say, using void* instead:
gives no warnings but you have told the compiler not to check the types.
In summary, my understanding is that g++ does make std::complex<float>* point to the internal float data but the linker LTO warning is saying that this is implementation dependent and not guaranteed.
|
Sun 17 Jul 2016 01:00:34 AM UTC, comment #2:
The existing code in schur.cc and crsf2csf.f assumes that there is an implicit conversion from "std::complex<float>" (C++ FloatComplex) to "float _complex_ *" (in the extern "C" {} declaration) to Fortran complex. The linker LTO warnings and simple example show that g++ doesn't guarantee that this will work. The proposed diff makes these implicit type conversions explicit. I think that at the least the reinterpret_cast<> in schur.cc is required to suppress the warnings. With gfortran Fortran subroutines return void.
I am using FC24 gcc x86_64 6.1.1-2 and building with:
For the existing code the linker output for liboctave starts with (complete output attached):
(file #37916)
|
Sat 16 Jul 2016 11:26:44 AM UTC, original submission:
Compiling and linking with gcc, g++ and gfortran flags including -flto gives warnings like:
A possibly incomplete list of the Fortran subroutines affected is crsf2csf, zrsf2csf, zdconv2i, zdconv2o, csconv2i, csconv2o, cconv2i, cconv2o, cbiry, cairy, cbesy, cbesk, cbesj, cbesi, cbesh, xcdotu, xcdotc, xilaenv, xzdotu, xzdotc.
The following patch silences the warnings for crsf2csf:
My understanding is that C++11 arranges that "__complex__ float" and "std::complex<float>" are made interchangeable by reinterpret_cast<>. See:http://en.cppreference.com/w/cpp/numeric/complex
For example:
gives:
I'm not sure what happens on the Fortran side when octave is configured with --enable-64.
The above patch does nothing for LTO warnings about naming differences inside Fortran COMMON blocks in the odepack code. For example:
|