Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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.

like image 582
NoSenseEtAl Avatar asked Dec 16 '21 12:12

NoSenseEtAl


2 Answers

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)

like image 54
ChrisMM Avatar answered Oct 11 '22 03:10

ChrisMM


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.

like image 35
Drew Dormann Avatar answered Oct 11 '22 01:10

Drew Dormann