1<?xml version="1.0" encoding="utf-8" ?> 2<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 3<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> 4<!-- Copyright Aleksey Gurtovoy 2006. Distributed under the Boost --> 5<!-- Software License, Version 1.0. (See accompanying --> 6<!-- file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) --> 7<head> 8<meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> 9<meta name="generator" content="Docutils 0.3.6: http://docutils.sourceforge.net/" /> 10<title>THE BOOST MPL LIBRARY: Broken Integral Constant Expressions</title> 11<link rel="stylesheet" href="../style.css" type="text/css" /> 12</head> 13<body class="docframe"> 14<table class="header"><tr class="header"><td class="header-group navigation-bar"><span class="navigation-group"><a href="./portability.html" class="navigation-link">Prev</a> <a href="./incomplete-support-for.html" class="navigation-link">Next</a></span><span class="navigation-group-separator"> | </span><span class="navigation-group">Back <a href="./incomplete-support-for.html" class="navigation-link">Along</a></span><span class="navigation-group-separator"> | </span><span class="navigation-group"><a href="./portability.html" class="navigation-link">Up</a> <a href="../index.html" class="navigation-link">Home</a></span><span class="navigation-group-separator"> | </span><span class="navigation-group"><a href="./tutorial_toc.html" class="navigation-link">Full TOC</a></span></td> 15<td class="header-group page-location"><a href="../index.html" class="navigation-link">Front Page</a> / <a href="./technical-details.html" class="navigation-link">Technical Details</a> / <a href="./portability.html" class="navigation-link">Portability</a> / <a href="./broken-integral-constant.html" class="navigation-link">Broken Integral Constant Expressions</a></td> 16</tr></table><div class="header-separator"></div> 17<div class="section" id="broken-integral-constant"> 18<h1><a class="toc-backref" href="./portability.html#id74" name="broken-integral-constant">Broken Integral Constant Expressions</a></h1> 19<p>This is probably the most surprising of the portability issues 20we're going to discuss, not least because for many C++ programmers, their everyday 21experience seems to indicate no problems in this area whatsoever. After all, 22integer compile-time computations along the lines of:</p> 23<pre class="literal-block"> 24enum flags { 25 flag1 = (1 << 0) 26 , flag2 = (1 << 1) 27 , flag3 = (1 << 2) 28 ... 29 }; 30</pre> 31<p>are <em>very</em> commonplace in C++, and there is hardly a compiler out 32there that cannot handle this correctly. While arithmetic by 33itself is indeed rarely problematic, when you are trying to mix it 34with templates on certain deficient compilers, all kinds of new 35issues arise. Fortunately, as with the rest of the portability 36issues we're discussing here, the problem fades into past as new 37compiler versions are released. The majority of most recent 38compilers of many vendors are already free from these issues.</p> 39<div class="section" id="the-problem"> 40<h2><a name="the-problem">The Problem</a></h2> 41<p>The problem is in fact multi-faceted; there are a number of 42different subissues. Some are present in one set of compilers, 43some are in another, and it's not uncommon for a code that works 44for one compiler to break another one and vice-versa. If this 45sounds like a maintenance nightmare to you, it is! If you are 46interested in the specific list of issues, please refer to John 47Maddock's excellent "<a class="reference" href="http://www.boost.org/more/int_const_guidelines.htm" target="_top">Coding Guidelines for Integral Constant 48Expressions</a>" summary. For the purpose of our discission here, it 49is sufficient to say that if your code has to work on one of the 50compilers listed as problematic in this area, you can safely assume 51that if you decide to fight them on a case-by-case basis, chances 52are that you won't be able to maintain your sanity for very long.</p> 53</div> 54<div class="section" id="the-symptoms"> 55<h2><a name="the-symptoms">The Symptoms</a></h2> 56<p>On the positive side, when you have an issue with integral 57arithmetic, the diagnostics are almost always straightforward: 58usually the error message refers you to the exact place in the code 59that is causing problems, and the essence of issue is obvious from 60the error's text, or it becomes obvious once you've encountered the 61same error a couple of times. For instance, if we throw this 62well-formed fragment at MSVC 7.1 (otherwise an excellent compiler!)</p> 63<pre class="literal-block"> 64void value(); 65 66// compares two Integral Constants 67template< typename N1, typename N2 > struct less 68 : bool_< (N1::value < N2::value) > // line #8 69{ 70}; 71</pre> 72<p>we get:</p> 73<pre class="literal-block"> 74portability.cpp(8) : warning C4346: 'N2::value' : dependent name is not a type 75 prefix with 'typename' to indicate a type 76 portability.cpp(10) : see reference to class template instantiation 'less<N1,N2>' being compiled 77portability.cpp(8) : error C2143: syntax error : missing ',' before ')' 78portability.cpp(9) : error C2143: syntax error : missing ';' before '{' 79portability.cpp(10) : error C2143: syntax error : missing ';' before '}' 80portability.cpp(10) : fatal error C1004: unexpected end of file found 81</pre> 82<p>The errors themselves are far from being ideal, but at least we are 83pointed at the correct line and even the correct part of the 84line. The above basically reads as "something's wrong between the 85parentheses", and that plus the "syntax error" part is usually 86enough of the clue.</p> 87</div> 88<div class="section" id="the-solution"> 89<h2><a name="the-solution">The Solution</a></h2> 90<p>Despite the fact the problems are so numerous and multi-faceted and 91the workarounds are conflicting, the problems can be hidden 92reliably beneath a library abstraction layer. The underlaying idea 93is very simple: we can always wrap the constants in types and pass 94those around. Then all that is left is to implement algebraic 95metafunctions that operate on such wrappers, once, and we are home 96safe.</p> 97<p>If this sounds familiar to you, probably it's because you have 98already took a look at the MPL and know that the approach we just 99described is in fact <em>the</em> standard way of doing arithmetic in the 100library. Although it's motivated by more general observations, 101this fact comes very handy for the library users that care about 102portability of their numerically-heavy metaprograms. The MPL 103primitives are already there, and more importantly, they already 104implement the necessary workarounds, so your numeric code just 105works. In fact, if you stay within the library's type-wrapper 106idioms, these particular problems never "leak" out of its 107abstraction layer.</p> 108<p>On a final note, there is a price of avoiding built-in arithmetics 109altogether, namely decreased readability and, on some compilers, 110increased compile-time overhead. Still, in majority of cases, the 111benefits of type-based arithmetics overweight its small 112shortcomings.</p> 113</div> 114</div> 115 116<div class="footer-separator"></div> 117<table class="footer"><tr class="footer"><td class="header-group navigation-bar"><span class="navigation-group"><a href="./portability.html" class="navigation-link">Prev</a> <a href="./incomplete-support-for.html" class="navigation-link">Next</a></span><span class="navigation-group-separator"> | </span><span class="navigation-group">Back <a href="./incomplete-support-for.html" class="navigation-link">Along</a></span><span class="navigation-group-separator"> | </span><span class="navigation-group"><a href="./portability.html" class="navigation-link">Up</a> <a href="../index.html" class="navigation-link">Home</a></span><span class="navigation-group-separator"> | </span><span class="navigation-group"><a href="./tutorial_toc.html" class="navigation-link">Full TOC</a></span></td> 118</tr></table></body> 119</html> 120