Is there a reason why implementations allow instantiation of std::complex with unsupported types
Asked Answered
U

2

18

edit note: originally question said illegal where now it says unspecified.

Thanks to video comment section of Jason Turner video recently I learned that std::complex<int> is unspecified.

But all(AFAIK) implementations seem to happily compile

std::complex<int>

But some functions like std::abs() are broken for std::complex<int>, so it's not actually usable in those mainstream implementaitons.


I wonder if there is some reason why detection for "bad" types was never implemented. I know that std lib implementations need to work with older standards so they can not just stuck std::floating_point concept everywhere, but even before C++20 we had ways to constrain templates.

In other words: is this just "would be nice, but we dont have time" issue, or is there some compatibility reason to keep this compiling. Only thing I can think of is that some people are using std::complex and std lib "manufacturers" do not want to obviously break their already broken code.

Uncivil answered 16/12, 2021 at 12:56 Comment(4)
To a mathematician, there is no requirement that the "real" and "imaginary" parts of complex numbers be real, let alone that they be floating point values. Complex numbers are also a special case of more general concepts - such as hypercomplex numbers.Iridissa
@Iridissa my guess is that they did not want to handle the abs or integral complex number returning a float/double (different type). std::hypot fixes that AFAIK... en.cppreference.com/w/cpp/numeric/math/hypot (8)Uncivil
That it compiles but is unspecified did not mean that it results in undefined behavior or other mad things. It simply leaves open how it will be work if it is implemented and this is part of vendors documentation. If you take a short look to gcc STL sources you will find that it is working as expected. And it has nothing to do with c++20 nor the existence of concepts or is_floating_point traits. To make it not compile can be done also with c++03.Ecphonesis
@Ecphonesis it does not work correctly, std::abs is broken for complex of int.Uncivil
S
15

It is actually not illegal, it is unspecified;

From [complex.numbers]/2

The effect of instantiating the template complex for any type other than float, double, or long double is unspecified.

Unspecified, from [defns.unspecified] means

unspecified behavior behavior, for a well-formed program construct and correct data, that depends on the implementation [Note 1 to entry: The implementation is not required to document which behavior occurs. The range of possible behaviors is usually delineated by this document. —end note]

(references from N4860 (C++20 draft)

Simms answered 16/12, 2021 at 12:59 Comment(4)
It has been unspecified in all C++ standards since 1998.Iridissa
With concepts added in C++20, why hasn't the complex template been limited to float point types? Did the ISO C++ committee give a reason?Sherrer
@UriRaz, because implementations are allowed to have a functioning complex type for other types; why take away that ability?Simms
@Simms Seems reasonable if its useful, e.g. complex from ints, it would be specified, otherwise blocked.Sherrer
S
13

Is there a reason why implementations allow instantiation of std::complex with unsupported types?

I wonder if there is some reason why detection for "bad" types was never implemented.

Both unspecified behavior (what you are describing) and undefined behavior are valuable in that they allow for new behavior in future standards.

If a future C++ standard were to implement a long long double or decimal type, then std::complex could also be revised to support it.

It it were someday decided that std::complex<int> has great importance, a future standard could promise to implement it.

If, instead, the standard had promised to "detect 'bad' types", these revisions could not happen without putting C++ standards in conflict.

Slickenside answered 16/12, 2021 at 13:41 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.