Bug 53429 - libstdc++ should guarantee not to expose complex::{imag,real} so it supports both C++98 and C++11
Summary: libstdc++ should guarantee not to expose complex::{imag,real} so it supports ...
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: libstdc++ (show other bugs)
Version: 4.8.0
: P3 normal
Target Milestone: 4.8.0
Assignee: Not yet assigned to anyone
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2012-05-21 03:59 UTC by Jeffrey Yasskin
Modified: 2016-07-08 11:54 UTC (History)
3 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2012-05-22 00:00:00


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Jeffrey Yasskin 2012-05-21 03:59:18 UTC
The non-const overloads of std::complex::real and std::complex::imag go from returning _Tp& to _Tp in C++98 vs C++11: http://gcc.gnu.org/viewcvs/trunk/libstdc%2B%2B-v3/include/std/complex?view=markup.  libstdc++ includes explicit instantiations of operator<< and operator>> with complex arguments: http://gcc.gnu.org/viewcvs/trunk/libstdc%2B%2B-v3/src/c%2B%2B98/complex_io.cc?view=markup. These operator<< and operator>> overloads call complex::real() and complex::imag(). If those calls are inlined (which is likely), so that no weak definition of real() and imag() is exposed to users of the library, then I believe all is well. However, if the compiler decides not to inline them, then people linking libstdc++ from the other version of the language may wind up with two conflicting weak definitions of the symbols.

I think marking them as alwaysinline would guarantee compatibility.
Comment 1 Jeffrey Yasskin 2012-05-21 04:03:26 UTC
So far, this is purely a theoretical incompatibility. I haven't actually seen a compiled libstdc++.so that exposes a version-specific complex::{imag,real}.
Comment 2 Richard Biener 2012-05-21 09:23:07 UTC
Note that C++98 and C++11 are not compatible anyway, for example due to the
changed way which classes are considered POD.
Comment 3 Jeffrey Yasskin 2012-05-21 15:30:45 UTC
Richard, I'm not asking that it be possible to link together code compiled in C++98 and C++11 mode. I'm asking that gcc be able to build in C++11 mode at all. If libstdc++.so exposed the c++98 version of complex::real(), then all C++11 programs that used complex would be potentially broken.

Another way to fix this would, of course, be to either expose a configuration option to build libstdc++.so in C++11 mode or to install two different .so files in parallel, but doing that seems unnecessarily hostile to users when it would be pretty easy to guarantee that the one .so works for both versions of the language.
Comment 4 Paolo Carlini 2012-05-21 15:59:44 UTC
Before fiddling with always inline, I would rather add 3 overloads of operator<< for float, double and long double, using __rep instead of real and imag. But I don't have a strong opinion about the PR (I have it about not using the attribute ;) if somebody wants to do something, please double check with Gaby.
Comment 5 Jeffrey Yasskin 2012-05-22 12:58:14 UTC
Specializing operator<< sounds fine too. Adding Gaby for his opinion, and reopening since I'm not sure Richard understood the request.
Comment 6 Jonathan Wakely 2016-07-08 11:54:53 UTC
(In reply to Jeffrey Yasskin from comment #3)
> Richard, I'm not asking that it be possible to link together code compiled
> in C++98 and C++11 mode. I'm asking that gcc be able to build in C++11 mode
> at all.

Even if we build GCC in C++11 (or C++14) mode, some pieces of libstdc++ get built with -std=gnu++98 explicitly. That's why they're in the libstdc++-v3/src/c++98 directory.

> If libstdc++.so exposed the c++98 version of complex::real(), then
> all C++11 programs that used complex would be potentially broken.

I don't think this is true now, because those functions are abi-tagged for C++11 and later, so C++11 programs would not use the symbols exported from the library (assuming such symbols existed, and if they did the check-abi testsuite target would fail for our primary targets, so we'd notice and it wouldn't just happen silently due to bad luck and different inlining decisions).

So I think this was fixed for 4.8.0 by r193445, but please reopen if I'm missing something and a potential problem still exists.

> Another way to fix this would, of course, be to either expose a
> configuration option to build libstdc++.so in C++11 mode or to install two
> different .so files in parallel, but doing that seems unnecessarily hostile
> to users when it would be pretty easy to guarantee that the one .so works
> for both versions of the language.

We definitely don't want two libs.