typeid(complex<double>(0.0,1.0)) != typeid(1.0i)
c++, c++11, complex-numbers, user-defined-literals
Solution
The behaviour of the program depends on the language standard mode of gcc:
There is a gcc extension for a built-in literal suffix `i` that produces C99 complex numbers. Those are distinct built-in types like `_Complex double`, as opposed to the "user-defined" class (template specialization) `std::complex<double>` used in C++.
In C++14, C++ now has a user-defined literal suffix `i` for complex numbers. That is, a function `complex<double> operator"" i(long double)` within the `std::literals::complex_literals` inline namespace.
Those two literal suffixes are competing:
In C++11 mode, only the built-in extension is possible, but it is an extension. Hence, gcc only allows it in `-std=gnu++11` mode and even warns you about it. Strangely enough, clang allows it even in `-std=c++11` mode.
In strict C++14 mode (`-std=c++14` or `-std=c++1y`), the built-in extension must be disabled to remove ambiguity (as far as I can tell), hence both gcc and clang selecting the user-defined literal suffix.
In the gnu-extension-C++14 mode `-std=gnu++14`, gcc chooses the built-in suffix (for backwards-compatibility?), whereas clang chooses the user-defined suffix. This looks strange, and I'd suggest looking for or filing bug reports here.
Depending on which literal suffix is chosen, you either get the built-in type `_Complex double` or some `std::complex<double>`.
Problem
Using `gcc 4.9` I found that types generated with type literal for complex numbers are not the same as when created by conventional means, i.e.: ``` typeid(complex<double>(0.0,1.0)) != typeid(1.0i) ``` - Am I making a mistake here? - Is this a compiler bug or intended standard behavior? - If intended standard behavior: What is the rationale behind? Adding the missing MCVE ``` #include <complex> using std::complex; using namespace std::literals::complex_literals; #include <iostream> using std::cout; using std::endl; #include <typeinfo> int main(int argc, char* argv[]) { if (typeid(complex<double>(0.0, 1.0)) == typeid(1.0i)) cout << "types are same as expected" << endl; else cout << "types are unexpectedly not the same" << endl; cout << 1.0i*1.0i << endl; cout << complex<double>(0.0, 1.0)*complex<double>(0.0, 1.0) << endl; } ``` Compile instructions: ``` g++ -std=gnu++14 complex.cpp -o complex.exe ``` Output: ``` types are unexpectedly not the same 1 (-1,0) ``` Interestingly the literal does not even seem to be a proper imaginary number. (I am sure I am overlooking something...)