Dr. Carlo Pescio|
Binary Constants: an update
Since publication of the article in the C/C++ Users Journal, several people have sent me some suggestions on how to eliminate the problem of (e.g.) 011 being interpreted as an octal constant by the compiler, therefore defeating the conversion to boolean. However, all the suggestions were along the lines I've sketched in my article, namely to add digits through the macro, and remove them in the metaprogram. As I said in the article itself, I don't particularly like a solution which ties the metaprogram and the macro too much.
More recentely I got a new idea about how to remove the problem. It does apply to the macro, but does not require any changes on the metaprogram side, so you are still free to use the metaprogram directly if you want, and gain extra safety if you call it through the macro.
The idea is very simple: replace the BIN_BYTE macro:
#define BIN_BYTE( N ) \ ((unsigned int)BinByte< (N) > :: value)with the following:
#define BIN_BYTE( N ) \ ((unsigned int)BinByte< (unsigned long)(N.0) > :: value)That way, if you call it as (e.g.) BIN_BYTE< 011 >, 011 gets expanded to (unsigned long)(011.0). The C++ standard mandates that the longest valid character sequence must be considered, and in this case 011.0 forms a floating point number, so the "octal rule" does not apply. Therefore, after conversion to unsigned long, we get 11 as expected, and that's what is passed to the metaprogram.
To say it all, the new macro leaves another minor
problem open: a call like BIN_BYTE( (1) ) will now fail because
of a syntax error; however, I consider this largely less frequent
than (e.g.) BIN_BYTE( 0101 ). Therefore, I warmly recommend to
use the new macro instead of the old one.