19

The following code with VS2010 prints 0, contrary to my expectations:

#include <complex>
#include <iostream>

using namespace std;

int main(void)
{
    complex<int> z(20, 200);
    cout << abs<int>(z) << endl;
    return 0;
}

It works fine when the type is double.

PeeHaa
  • 71,436
  • 58
  • 190
  • 262
Artium
  • 5,147
  • 8
  • 39
  • 60

2 Answers2

23

According to the C++ ISO spec, §26.2/2:

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

In other words, the compiler can do whatever it wants to when you instantiate complex<int>. The fact that you're getting 0 here is perfectly well-defined behavior from a language perspective.

For a comparison - on ideone's version of gcc, this code doesn't even compile. That's another perfectly valid option.

Hope this helps!

templatetypedef
  • 362,284
  • 104
  • 897
  • 1,065
  • 1
    Huh, I'm not even allowed to use my own real number type? That's disappointing. – Paul Manta Jun 19 '12 at 20:15
  • @PaulManta- Yeah, I guess not. I have no idea why this is. – templatetypedef Jun 19 '12 at 20:15
  • 1
    Thank you for your answer. Returning 0, 200 or 42 when behavior is unspecified might be indeed according to a standard, but surely it is quite a pitfall for the casual programmer like me. – Artium Jun 19 '12 at 20:32
  • @Artium: There are only two pitfalls: one, you did not properly read the specification, and two, the compiler did not produce an error, which it should have done. – Puppy Jun 19 '12 at 20:33
  • @DeadMG- Unfortunately, the spec doesn't require the compiler to produce any diagnostics: "The implementation is not required to document which behavior occurs" (§1.3/13) – templatetypedef Jun 19 '12 at 20:35
  • @templatetypedef: Sure, but that does not mean that there is no burden for them to produce an error. – Puppy Jun 19 '12 at 20:36
  • 1
    Technically, that is exactly what *unspecified behavior* means -- there is no burden on them to do anything at all, up to and including accidentally doing exactly what you expected, as long as its consistent about it. – Michael Edenfield Jun 20 '12 at 02:14
6

On MinGW 4.6.2 it prints 200.

However, in the C++ ISO standard section 26.2.2:

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

So your build environment is exhibiting undefined behavior for complex<int>, which is not against the standard.

As templatetypedef pointed out, ideone's C99 compiler (GCC 4.3.4) refuses to compile it altogether.

Unsigned
  • 9,640
  • 4
  • 43
  • 72
  • @DeadMG - The version used in `templatetypedef`'s example is 4.3.4, for C99. Your link uses C++0x, which is version 4.5.1, see [this page](http://ideone.com/samples#sample_lang_44) – Unsigned Jun 19 '12 at 20:46