3 ms·
I don't think focusing on a particular case is helpful, because what they're really talking about is the entire C++ type system. This could happen in any case
by makecheck 16y ago
I don't think focusing on a particular case is helpful, because what they're really talking about is the entire C++ type system. This could happen in any case where types are converted: calling functions, assigning variables...whether or not any printing or typedefs or chars are involved. You could see surprising behavior anywhere, and arguably in places where it is a lot harder to debug.
The "explicit" keyword for constructors addresses part of the problem, but not all of it. The real issue is one of programming style. Personally, I feel this is a case where C++ programmers should think more like C programmers, and not be offended by having to give functions different names, or otherwise making things more distinct when the behavior is totally different anyway.
If I have to call handleChar() and handleInt() with an "if" statement, instead of relying on one of the 12 overloads of handleAnything() to perform magic, I think that is fine because it will one day save me hours of debugging. Notice that printf("%c", c) has pretty damned clear behavior, and it requires someone to say the equally-clear printf("%d", (int)c) to get a number when they want a number; this might not be C++-like, but it's the right way to think about the problem.
- Someone 16y agoOn the other hand, to make things really interesting, one could do typedef signed char int8_t; to 'solve' the problem that char and int8_t are the same type. That also fixes a portability problem: AFAIK, there is no guarantee that 'char' is signed.
- nuxi 16y ago> Notice that printf("%c", c) has pretty damned clear behavior, and it requires someone to say the equally-clear printf("%d", (int)c) to get a number when they want a number; It does have a clear behaviour, but it's possibly different from what you think. From your examples I'm assuming "c" is a char variable - since you're casting it to int in the second example - which is then (incorrectly) passed to printf with "%c". Both %c and %d require an integer parameter, so "c" should be an integer to begin with (thus no need for a cast). Nitpicking, I know, but such code can lead to many subtle bugs.
- makecheck 16y agoThe C library should cast the parameter down to a char when "%c" is used; the only reason it allows an int is for the "%lc" case.
- nuxi 16y agoIt does cast it down (to unsigned char). The requirement for int however was is not for "%lc", it was already in C89. I suspect it has to do with default integral promotions for (variadic) function parameters - which I incorrectly disregarded when replying. So the original code is correct, my reply wasn't.