Hello, While experimenting with -std=c++0x and libstdc++ built at -O0 [1], I noticed that this sample code does not produce the expected result: ==================8<>=============== #include <iostream> #include <complex> int main() { const std::complex<float> cf (23., 101.); std::cout << cf.real() << '\n'; std::cout << cf << '\n'; return 0; } ==================8<>=============== That is, with -std=c++0x it prints: 23 (0,101) and without -std=c++0x it prints: 23 (23,101) This is because the call to cf.real() makes the compiler generate a 'c++0x' variant of std::complex<float>::real() const, which is also called implicitly by the library when printing the complex. But the library expects the non 'c++0x' version. Admittedly, libstdc++ seems to be expected to compiled at -O2 and thus std::complex<float>::real() is normally inlined, but I am wondering whether there might be other functions in libstdc++ which would not be inlined at -O2 in the library itself, and thus subject to the same problem. One way of having compliant libraries for me is to use multilib, but understanding the root cause of such errors might not be easy for the average user. I am not sure this is really a bug (is building libstdc++ at -O0 supported?), but at least I think it might be worth checking that other functions whose prototype changes with -std=c++0x are always inlined in the library itself. [1] I built libstdc++ at -O0 inadvertently, by overriding CFLAGS (not including -O2) before building GCC.
If you look at libstdc++-v3/include/std/complex: [...] #ifdef __GXX_EXPERIMENTAL_CXX0X__ // _GLIBCXX_RESOLVE_LIB_DEFECTS // DR 387. std::complex over-encapsulated. constexpr _Tp real() const { return _M_real; } [...] #else [...] /// Return real part of complex number. const _Tp& real() const { return _M_real; } [...] #endif You can see that depending of __GXX_EXPERIMENTAL_CXX0X__ (automatically defined with -std=c++0x), the type of the value returned by real() is different.
(In reply to comment #0) > I am not sure this is really a bug (is building libstdc++ at -O0 supported?), Yes, the --enable-libstdcxx-debug configure option builds an alternative libstdc++.so with -O0 (but I can't reproduce this when using that lib)
Not sure how/if it matters: I am looking at a cross gcc for arm-none-eabi, built with --disable-shared.
Something seems fishy on x86_64-linux too, with the library built -O0 and -std=c++11 I see random segfaults. But since the problem seems simply that at -O0 we have these *additional* unwanted exports: 000000000008031e W std::complex<double>::imag() const 0000000000080310 W std::complex<double>::real() const 0000000000080394 W std::complex<long double>::imag() const 0000000000080386 W std::complex<long double>::real() const 00000000000802ac W std::complex<float>::imag() const 000000000008029e W std::complex<float>::real() const 00000000000802e4 W std::complex<double>::complex(double, double) 00000000000802e4 W std::complex<double>::complex(double, double) 0000000000080330 W std::complex<double>::operator=(double) 0000000000080358 W std::complex<long double>::complex(long double, long double) 0000000000080358 W std::complex<long double>::complex(long double, long double) 00000000000803a6 W std::complex<long double>::operator=(long double) 0000000000080276 W std::complex<float>::complex(float, float) 0000000000080276 W std::complex<float>::complex(float, float) 00000000000802be W std::complex<float>::operator=(float) I suppose the fix should be straightforward: just tighten the linker map and prevent that from happening.
linker script, I meant
Created attachment 27033 [details] Very lightly tested so far Appears to work as expected. Maybe submitter can test it in his config: just apply the patchlet and rebuild (library only is fine) as usual.
It doesn't work in my context: - symbol versioning does not apply to static libraries (as already said, I'm using --disable-shared) - the problem is not that the library is exporting unwanted symbols, but that it is referencing symbols which happen to be defined in the user main.o with a different prototype. main.o defines and calls real() libstdc++.a (complex_io.o) calls real(), but expects the version defined in libstdc++.a which has a different prototype from the one in main.o. However, it uses the version in main.o by link rules. Another possible fix could be to add the always_inline attribute in the library, or make sure to distinguish both prototypes.
For sure, anyway, at -O0 the library *is* exporting unwanted symbols. I'm not sure that at this time we can really support what you want.
(In reply to comment #2) > (In reply to comment #0) > > I am not sure this is really a bug (is building libstdc++ at -O0 supported?), > > Yes, the --enable-libstdcxx-debug configure option builds an alternative > libstdc++.so with -O0 (but I can't reproduce this when using that lib) I have experimented with this configure option. I didn't know about it: what is the intended way of using the debug libraries? I have add -L..../debug to my link command, and I do reproduce the problem in this context: - target arm-none-eabi - --disable-shared # Using default libs, built at -O2 $ arm-none-eabi-g++ cplx.cxx -o cplx.u -mcpu=cortex-a9 -std=c++0x $ qemu-system-arm -semihosting -cpu cortex-a9 -nographic -kernel ./cplx.u 23 (23,101) # Using debug libs, built at -O0 $ arm-none-eabi-g++ cplx.cxx -o cplx.u -mcpu=cortex-a9 -std=c++0x -L .../lib/debug $ qemu-system-arm -semihosting -cpu cortex-a9 -nographic -kernel ./cplx.u 23 (0,101)
(In reply to comment #9) > I have experimented with this configure option. I didn't know about it: what is > the intended way of using the debug libraries? I use debug/libstdc++.so via LD_LIBRARY_PATH when I want to run in gdb and step-through code in the library. i.e. I link as normal, but switch to using the debug lib at run-time. Obviously if using static linking that doesn't work so you'd have to decide to use that lib at link-time. I mentioned it here because it's a common (and supported) way to get a libstdc++ built with -O0 while keeping the primary libs built with the usual flags (-O2 etc.)
I have proposed a patch related to this problem some time ago, which received no feedback: http://gcc.gnu.org/ml/gcc-patches/2012-03/msg01855.html
Patches for libstdc++ should be sent to the libstdc++ list as well as gcc-patches. That's probably why you didn't get any feedback.
Oh I see it isn't specific to libstdc++. You'll just have to push on the gcc-patches list for review then. It helps if you describe the problem it solves in detail, and confirm it was tested successfully, stating on which platform(s).
The original problem should be fixed long ago, because those functions use the abi_tag now.
(In reply to Jonathan Wakely from comment #14) > The original problem should be fixed long ago, because those functions use > the abi_tag now. I think this was fixed for gcc 4.8.0 by r0-120238-g7a3a9e6821ff5e so I'm going to close it.