The same problem comes up in other situations BTW. As well as the type of literal "0" being ambiguous, there's many similar situations that a C++ programmer should be aware of. e.g. what's the type of the literal "1" below, and does the assertion fail?unsigned long long mask = 1<<48; assert( mask == 0x1000000000000 );
The literal "1" has type int. Probably "1ul" (if the compiler has 64-bit longs) or "1ull" was intended. [EDIT: Actually, the way the code is written, "1ull" was intended for sure.]
I am very careful to always use literals with the type I intend, since I was bitten by this one:
double limit_price = order.is_market() ? 0 : order.limit_price();At the time when I wrote this code Order::limit_price() used to return a double, and all was good. Then someone changed that to return a type Price, which provided an implicit conversion to double. The person doing that is a C++ expert, he tested the code, and it worked fine. Then we changed compilers from gcc-2.95.2 to gcc-3.4 (yeah, this is years ago), and then prices started to get truncated to integer values. This was not caught when testing the new compiler version (because someone messed up), and we ended up sending incorrect reports to a market regulator for several days. I spent about two weeks cleaning up the mess.
It turns out the C++ standard specifies that truncating to int is the correct behavior. Recent versions of g++ will warn about this, but it took them a long time to do so.
Since then, I write 0.0 if I intend it to be a double, 0.0f if I intend it to be a float, etc. I also don't like implicit conversions and I would much rather have an explicit Price::as_double() method that I need to call explicitly.