320 lines
17 KiB
HTML
320 lines
17 KiB
HTML
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||
<html>
|
||
<head>
|
||
<meta content="text/html; charset=windows-1252"
|
||
http-equiv="content-type">
|
||
<title>limitations.html</title>
|
||
<link rel="stylesheet" type="text/css" href="../styles.css">
|
||
<style>
|
||
u { font-weight: normal; text-decoration: none; }
|
||
</style>
|
||
</head>
|
||
<body>
|
||
<h3>Preprocessor library limitations</h3>
|
||
<blockquote>
|
||
<p>The Boost preprocessor library has always had certain specific
|
||
limitations, which are specifically explained in other areas of
|
||
this documentation and are implemented as object-like macros in
|
||
the header file config/limits.hpp. These limitations largely
|
||
detail the maximum number for certain features in the library.
|
||
These maximums have been chosen in order to accommodate the
|
||
large number of compilers and their preprocessors which the
|
||
library supports, in order to provide a lowest common set of
|
||
limits with which the vast majority of these compilers can work
|
||
successfully. This reflects the situation that the C/C++
|
||
standard rarely specifies preprocessor limitations for compilers
|
||
but rather allows each compiler to choose whatever limitations
|
||
it deems necessary in its preprocessor. While this allows
|
||
individual compilers to largely choose what preprocessor
|
||
limitations it deems necessary, it makes it more difficult for a
|
||
preprocessor library like this one to work with a large number
|
||
of preprocessors across a number of operating system platforms.
|
||
The difficulty of this situation means that this Boost
|
||
preprocessor library has chosen fairly conservative limitations.<br>
|
||
</p>
|
||
<p>In fact the limitation macros, although indeed existing, have
|
||
never previously been used internally in the preprocessor
|
||
library code. Instead while the limitation macros do indeed
|
||
exist, the library has internally used fixed numbers equivalent
|
||
to what these macros represent. This historical situation most
|
||
probably reflects the fact that the library did not want the
|
||
end-user's possibly changing the limitations, by redefining the
|
||
macros in config/limits.hpp, to change how the library works and
|
||
therefore cause problems in using the library.<br>
|
||
</p>
|
||
<p>This situation has now changed and a number of the limitation
|
||
macros specified in config/limits.hpp are now used internally in
|
||
the library code when the preprocessor is C++ standard
|
||
conforming. This topic is therefore about how an end-user can
|
||
change the limitations of the library.<br>
|
||
</p>
|
||
</blockquote>
|
||
<h4>Type of limitations</h4>
|
||
<blockquote>
|
||
<p>The type of limitations in the Boost preprocessor library can
|
||
be divided as:<br>
|
||
</p>
|
||
<ul>
|
||
<li>Numbers</li>
|
||
<li>Sizes</li>
|
||
<li>Loops</li>
|
||
<li>Iterations</li>
|
||
</ul>
|
||
The library has support for numbers. This supports basic
|
||
arithmetic, comparisons, and logical operations. This support is
|
||
documented by the macro BOOST_PP_LIMIT_MAG, where 'MAG' is short
|
||
for "MAGNITUDE'. The current fixed maximum value is 256. This
|
||
means that the library supports numerical operations in the range
|
||
between 0 and 256.<br>
|
||
<br>
|
||
The library has support for the maximum sizes of higher level
|
||
types. These types are arrays, lists, seqs, tuples, and variadic
|
||
data. By sizes for these higher level constructs it is meant the
|
||
maximum number of elements of which a higher level construct can
|
||
consist. For arrays and tuples this value is documented by the
|
||
macro BOOST_PP_LIMIT_TUPLE while for variadic data this value is
|
||
documented by the macro BOOST_PP_LIMIT_VARIADIC. In both these
|
||
cases the current fixed maximum value is 64. For seqs the value is
|
||
documented by the macro BOOST_PP_LIMIT_SEQ, whose current fixed
|
||
value is 256. For lists there has never been a limitation macro
|
||
but in actual fact the limitation on the maximum number of list
|
||
elements is defined by the maximum number given above for
|
||
BOOST_PP_LIMIT_MAG. So a list, like a seq, has a default maximum
|
||
of 256 elements. The reason that the maximum number of elements
|
||
for arrays, tuples, and variadic data is 64 while for seqs and
|
||
lists it is the much larger value of 256 is because the
|
||
implementation of the former constructs often involves passing the
|
||
likewise number as parameters to internal macros and a number of
|
||
compilers have placed limitations on the number of parameters a
|
||
macro can have; so the much safer 64 was chosen so as to be able
|
||
to work with these compilers.<br>
|
||
<br>
|
||
The looping constructs consist of the control structure
|
||
BOOST_PP_WHILE and the repetition constructs BOOST_PP_FOR and
|
||
BOOST_PP_REPEAT. Each of these have a limitation macro, all
|
||
currently set to 256. This means that the loop can run at maximum
|
||
256 times. The corresponding limitation macros are
|
||
BOOST_PP_LIMIT_WHILE, BOOST_PP_LIMIT_FOR, and
|
||
BOOST_PP_LIMIT_REPEAT.<br>
|
||
<br>
|
||
Iteration constructs consist of local iteration and file iteration
|
||
constructs.The specifics are more fully discussed in their own
|
||
topics. The corresponding macro is BOOST_PP_LIMIT_ITERATION whose
|
||
value is 256.<br>
|
||
</blockquote>
|
||
<h4> Limitation dependencies</h4>
|
||
<blockquote>A number of the limitations are actually dependent on
|
||
other limitations. These are:<br>
|
||
<ul>
|
||
<li>BOOST_PP_LIMIT_MAG depends on BOOST_PP_LIMIT_WHILE. All the
|
||
arithmetic macros except for BOOST_PP_INC and BOOST_PP_DEC
|
||
depend on looping using BOOST_PP_WHILE. Similarly all the
|
||
comparison macros except for BOOST_PP_EQUAL and
|
||
BOOST_PP_NOT_EQUAL depend on BOOST_PP_WHILE. So whatever is
|
||
the value for BOOST_PP_LIMIT_MAG is also the value for
|
||
BOOST_PP_LIMIT_WHILE.</li>
|
||
<li>BOOST_PP_LIMIT_TUPLE depends on BOOST_PP_LIMIT_VARIADIC,
|
||
since array/tuple functionality often ends up calling variadic data
|
||
functionality. So while BOOST_PP_LIMIT_TUPLE can be smaller
|
||
than BOOST_PP_LIMIT_VARIADIC it can never be larger.<br>
|
||
</li>
|
||
<li>BOOST_PP_LIMIT_SEQ depends on BOOST_PP_LIMIT_MAG since the
|
||
total size of a seq must be at most the largest number. So
|
||
while BOOST_PP_LIMIT_SEQ could be smaller than
|
||
BOOST_PP_LIMIT_MAG it can never be larger.</li>
|
||
<li>BOOST_PP_LIMIT_FOR, BOOST_PP_LIMIT_REPEAT, and
|
||
BOOST_PP_LIMIT_ITERATION all depend on BOOST_PP_LIMIT_MAG.
|
||
While any of these values could be smaller than
|
||
BOOST_PP_LIMIT_MAG none of them can be larger.</li>
|
||
</ul>
|
||
</blockquote>
|
||
<h4>Changing the limitations</h4>
|
||
<blockquote>
|
||
<p>Limitations can be changed by the end-user defining a
|
||
limitation macro prior to including preprocessor library header
|
||
files. This can be done either in a source file or as part of a
|
||
compiler command line.<br>
|
||
</p>
|
||
</blockquote>
|
||
<blockquote>
|
||
<p>Before specifying which limitations can be changed a number of
|
||
items need to be emphasized:<br>
|
||
</p>
|
||
<ul>
|
||
<li>The limitations which can be changed can only be done for
|
||
C++ standard conforming preprocessors. You can use the macro
|
||
BOOST_PP_IS_STANDARD, invoking it as BOOST_PP_IS_STANDARD(),
|
||
to determine if your compiler has a C++ standard conforming
|
||
preprocessor. Almost all major compilers, including gcc and
|
||
clang, have C++ standard conforming preprocessors. Most
|
||
notably the default Visual C++ compiler is not a C++ standard
|
||
conforming preprocessor, but the new preprocessor for Visual
|
||
C++, available in Visual Studio 2019 and above, is a C++
|
||
standard conforming preprocessor. If you change a limitation
|
||
for a compiler that is not a C++ standard conforming
|
||
preprocessor the change is simply ignored and no preprocessor
|
||
error will occur. This is because any non-conforming
|
||
preprocessor does not actually include or use the macros in
|
||
the config/limits.hpp file.<br>
|
||
</li>
|
||
<li>WARNING ! WARNING ! WARNING ! Increasing limitations may
|
||
mean that preprocessors may fail because the compiler itself
|
||
can not handle the increase in the limitations. This may occur
|
||
because the compiler has an internal limit on the number of
|
||
parameters that can be passed to a macro, the number of nested
|
||
macro invocations, or even the amount of memory needed for the
|
||
preprocessor to expand a macro.</li>
|
||
<li>Except for possibly first including the preprocessor header
|
||
boost/preprocessor/config/config.hpp, changing any limitation
|
||
must be done before including Boost preprocessor headers in a
|
||
TU ( translation unit ) to work properly. Attempting to change
|
||
a limitation after including Boost preprocessor headers will
|
||
at worst lead to preprocessor errors and at best lead to UB (
|
||
undefined behavior ).</li>
|
||
<li>Limitations can only be changed to specific values as given
|
||
below. Attempting to change limitations to other than the
|
||
specific values will lead to the change being ignored or, if
|
||
incorrectly done after including Boost preprocessor headers, a
|
||
preprocessor error.</li>
|
||
</ul>
|
||
All the limitations whose default value is 256 can be changed to
|
||
either 512 or 1024, except for BOOST_PP_LIMIT_WHILE which can not
|
||
be changed.<br>
|
||
The two limitations whose default value is 64 can be changed to
|
||
128 or 256.<br>
|
||
<br>
|
||
For the individual limitations:<br>
|
||
<ul>
|
||
<li>BOOST_PP_LIMIT_MAG : When you change this limitation the
|
||
value of BOOST_PP_LIMIT_WHILE also changes so that it is equal
|
||
to BOOST_PP_LIMIT_MAG. This is because numerical computations
|
||
depend on the BOOST_PP_WHILE loop, and therefore
|
||
BOOST_PP_LIMIT_WHILE itself can not be changed. Also when you
|
||
change the BOOST_PP_LIMIT_MAG limitation the value of
|
||
BOOST_PP_LIMIT_SEQ, if it has not been also changed to be less
|
||
than BOOST_PP_LIMIT_MAG, is also changed to the value of
|
||
BOOST_PP_LIMIT_MAG. This is so that seqs, like lists, will
|
||
normally have the same maximum number of elements, as defined
|
||
by BOOST_PP_LIMIT_MAG, unless you decide otherwise and change
|
||
the BOOST_PP_LIMIT_SEQ yourself.<br>
|
||
</li>
|
||
<li>BOOST_PP_LIMIT_TUPLE: When you change this limitation the
|
||
value of BOOST_PP_LIMIT_VARIADIC also changes so that it is at
|
||
least equal to BOOST_PP_LIMIT_TUPLE if the value of
|
||
BOOST_PP_LIMIT_VARIADIC has not also been changed to be
|
||
greater than BOOST_PP_LIMIT_TUPLE. This is because
|
||
tuples/arrays depend on variadic functionality.</li>
|
||
<li>BOOST_PP_LIMIT_SEQ, BOOST_PP_LIMIT_FOR,
|
||
BOOST_PP_LIMIT_REPEAT, BOOST_PP_LIMIT_ITERATION: If you try to
|
||
set any of these values greater than the BOOST_PP_LIMIT_MAG
|
||
value, the particular limitation is set to equal the value of
|
||
BOOST_PP_LIMIT_MAG. This is because all of these limits depend
|
||
on the range of numerical values.</li>
|
||
</ul>
|
||
</blockquote>
|
||
<h4>Other considerations</h4>
|
||
<blockquote>
|
||
<p>There is no necessity to change any limitation if you are happy
|
||
with its default value. However if you decide to increase a
|
||
limitation you should be aware that doing so can affect both the
|
||
amount of memory used by the preprocessor and the speed in which
|
||
preprocessing is accomplished. In the first case some
|
||
preprocessors have been known to run out of memory if a
|
||
limitation value is increased, even though this should really
|
||
never happen in modern computer systems. In the latter case
|
||
preprocessing might become so slow that trying to use the
|
||
library with some increased limitation, and have your
|
||
preprocessing finish in some reasonable amount of time, becomes
|
||
impossible. The latter can occur when you are using lists or
|
||
seqs and while cycling through a large number of elements you
|
||
are also doing time consuming operations on each element value
|
||
which generates further macro looping. Nearly all arithmetic and
|
||
comparison operations involve further macro looping.<br>
|
||
</p>
|
||
<p>For lists and seqs there is functionality which uses the
|
||
BOOST_PP_FOR macro. If the maximum size for lists and seqs is
|
||
increased, by using BOOST_PP_LIMIT_MAG macro, you may also need
|
||
to define BOOST_PP_LIMIT_FOR to increase the maximum number of
|
||
'for' loops in order to cycle through all lists or seqs using
|
||
this functionality.<br>
|
||
</p>
|
||
<p>The BOOST_PP_WHILE construct is used internally for looping by
|
||
nearly all arithmetic and comparison macros as well as
|
||
internally by a number of other macros in the library which loop
|
||
through elements. While the construct can be called from within
|
||
an already running BOOST_PP_WHILE loop, it is possible to run
|
||
out of BOOST_PP_WHILE loops when this happens. In order to solve
|
||
this problem you can specify a BOOST_PP_LIMIT_MAG which is
|
||
larger than the maximum number you will ordinarily use. This
|
||
will give you twice the number of BOOST_PP_WHILE loops and will
|
||
keep you from running out of loops if you have to do arithmetic
|
||
computations while cycling through lists and seqs and the number
|
||
of lists and/or seqs you cycle through is anywhere near your
|
||
original maximum.<br>
|
||
</p>
|
||
</blockquote>
|
||
<h4>Testing limitations</h4>
|
||
<blockquote>
|
||
<p>The default testing of the preprocessor library, using Boost
|
||
Build's b2 command in the preprocessor test directory, only
|
||
tests the default limitations. If you want to test, within the
|
||
test directory, any of the non-default limitations which may be
|
||
set, you can do so by invoking the b2 command with any of these
|
||
explicit targets:<br>
|
||
</p>
|
||
<ul>
|
||
<li>preprocessor_128 : arrays, tuples, and variadics with up to
|
||
128 elements</li>
|
||
<li>preprocessor_256 : arrays, tuples, and variadics with up to
|
||
256 elements</li>
|
||
<li>preprocessor_512 : numbers, lists, seqs, looping, and
|
||
iteration constructs with 512 maximum</li>
|
||
<li>preprocessor_1024 : numbers, lists, seqs, looping, and
|
||
iteration constructs with 1024 maximum</li>
|
||
<li>preprocessor_tup : both the first and second items in this
|
||
list</li>
|
||
<li>preprocessor_num : both the third and fourth items in this
|
||
list</li>
|
||
<li>preprocessor_limits : all preprocessor limitations</li>
|
||
</ul>
|
||
If you invoke b2 with the last preprocessor_limits target your
|
||
testing may take awhile for your compiler. When you choose one of
|
||
the above targets, as in <code>'b2 preprocessor_limits'</code>,
|
||
the default tests are not run. If you want the default tests run,
|
||
along with any of the targets such as preprocessor_limits, your
|
||
command would be <code>'b2 . preprocessor_limits'</code>, where
|
||
the '.' notation means all the non-explicit ( aka default )
|
||
targets.<br>
|
||
</blockquote>
|
||
<blockquote> </blockquote>
|
||
<blockquote>
|
||
<ul>
|
||
</ul>
|
||
</blockquote>
|
||
<blockquote> </blockquote>
|
||
<b>See</b> <b>Also</b><br>
|
||
<ul>
|
||
<li><a href="../ref/is_standard.html">BOOST_PP_IS_STANDARD</a><br>
|
||
</li>
|
||
<li><a href="../ref/limit_mag.html">BOOST_PP_LIMIT_MAG</a></li>
|
||
<li><a href="../ref/limit_tuple.html">BOOST_PP_LIMIT_TUPLE</a></li>
|
||
<li><a href="../ref/limit_variadic.html">BOOST_PP_LIMIT_VARIADIC</a></li>
|
||
<li><a href="../ref/limit_seq.html">BOOST_PP_LIMIT_SEQ</a></li>
|
||
<li><a href="../ref/limit_while.html">BOOST_PP_LIMIT_WHILE</a></li>
|
||
<li><a href="../ref/limit_for.html">BOOST_PP_LIMIT_FOR</a></li>
|
||
<li><a href="../ref/limit_repeat.html">BOOST_PP_LIMIT_REPEAT</a></li>
|
||
<li><a href="../ref/limit_iteration.html">BOOST_PP_LIMIT_ITERATION</a><br>
|
||
</li>
|
||
</ul>
|
||
<hr size="1">
|
||
<div style="margin-left: 0px;"> <i><EFBFBD> Copyright Edward Diener 2020</i>
|
||
</div>
|
||
<div style="margin-left: 0px;">
|
||
<p><small>Distributed under the Boost Software License, Version
|
||
1.0. (See accompanying file <a
|
||
href="../../../../LICENSE_1_0.txt">LICENSE_1_0.txt</a> or
|
||
copy at <a href="http://www.boost.org/LICENSE_1_0.txt">www.boost.org/LICENSE_1_0.txt</a>)</small></p>
|
||
</div>
|
||
</body>
|
||
</html>
|