Search code examples
c++c++11clangcomplex-numbersuser-defined-literals

Why don't complex-number literals work in clang?


When I run this code on ideone.com, it prints (2,3):

#include <iostream>
#include <complex>

int main() {
    std::complex<double> val = 2 + 3i;
    std::cout << val << std::endl;
    return 0;
}

But when I use clang on macOS 10.11.6, I get no errors or warnings, but the output is (2,0):

$ clang --version
Apple LLVM version 7.3.0 (clang-703.0.31)
Target: x86_64-apple-darwin15.6.0

$ clang -lc++ test.cpp && ./a.out
(2,0)

What happened to the imaginary part? Am I doing something wrong?


Solution

  • I believe for this first example the compiler is using a GNU extension:

    -fext-numeric-literals (C++ and Objective-C++ only)
    

    Accept imaginary, fixed-point, or machine-defined literal number suffixes as GNU extensions. When this option is turned off these suffixes are treated as C++11 user-defined literal numeric suffixes. This is on by default for all pre-C++11 dialects and all GNU dialects: -std=c++98, -std=gnu++98, -std=gnu++11, -std=gnu++14. This option is off by default for ISO C++11 onwards (-std=c++11, ...).

    When I run it with clang I get (are you using -Wall -pedantic? :)):

    warning: imaginary constants are a GNU extension [-Wgnu-imaginary-constant]

    Either way, your code is not standard compliant. To use C++14 literals make the code:

    #include <iostream>
    #include <complex>
    using namespace std::complex_literals;
    int main() {
        std::complex<double> val = 2.0 + 3i;
        std::cout << val << std::endl;
        return 0;
    }
    

    From the documentation:

    These operators are declared in the namespace std::literals::complex_literals, where both literals and complex_literals are inline namespaces. Access to these operators can be gained with using namespace std::literals, using namespace std::complex_literals, and using namespace std::literals::complex_literals.