vmd_constraints.qbk 5.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576
  1. [/
  2. (C) Copyright Edward Diener 2011-2015
  3. Distributed under the Boost Software License, Version 1.0.
  4. (See accompanying file LICENSE_1_0.txt or copy at
  5. http://www.boost.org/LICENSE_1_0.txt).
  6. ]
  7. [section:vmd_constraints Macro constraints]
  8. When discussing the BOOST_VMD_IS_EMPTY macro I mentioned constraining input to
  9. the macro. Now I will discuss what this means in terms of preprocessor metaprogramming
  10. and input to macros in general.
  11. [heading Constrained input]
  12. When a programmer designs any kinds of callables in C++ ( functions, member functions etc. ),
  13. he specifies what the types of input and the return value are. The C++ compiler enforces this
  14. specification at compile time. Similarly at run-time a callable may check that its
  15. input falls within certain documented and defined boundaries and react accordingly
  16. if it does not. This is all part of the constraints for any callable in C++ and should
  17. be documented by any good programmer.
  18. The C++ preprocessor is much "dumber" than the C++ compiler and even with the preprocessor
  19. metaprogramming constructs which Paul Mensonides has created in Boost PP there is far less
  20. the preprocessor metaprogrammer can do at preprocessing time to constrain argument input
  21. to a macro than a programmer can do at compile-time and/or at run-time to constrain argument
  22. input to a C++ callable. Nevertheless it is perfectly valid to document what a macro expects
  23. as its argument input and, if a programmer does not follow the constraint, the macro will fail
  24. to work properly. In the ideal case in preprocessor metaprogramming the macro could tell whether
  25. or not the constraint was met and could issue some sort of intelligible preprocessing error
  26. when this occurred, but even within the reality of preprocessor metaprogramming with Boost PP
  27. this is not always possible to do. Nevertheless if the user of a macro
  28. does not follow the constraints for a macro parameter, as specified in the
  29. documentation of a particular macro being invoked, any error which occurs is the
  30. fault of that user. I realize that this may go against the strongly
  31. held concept that programming errors must always be met with some sort of compile-time or
  32. run-time occurrence which allows the programmer to correct the error, rather than a silent failure
  33. which masks the error. Because the preprocessor is "dumber" and cannot provide this occurrence
  34. in all cases the error could unfortunately be masked, despite the fact that the documentation
  35. specifies the correct input constraint(s). In the case of the already discussed
  36. macro BOOST_VMD_IS_EMPTY, this masking of the error could only occur with a preprocessor ( Visual C++ )
  37. which is not C++ standard conformant.
  38. The Boost PP library does have a way of generating a preprocessing error, without generating preprocessor
  39. output, but once again this way does not work with the non-conformant preprocessor of Visual C++. The means
  40. to do so using Boost PP is through the BOOST_PP_ASSERT macro. As will be seen and discussed later VMD has
  41. an equivalent macro which will work with Visual C++ by producing incorrect C++ output rather than a preprocessing
  42. error, but even this is not a complete solution since the incorrect C++ output produced could be hidden.
  43. Even the effort to produce a preprocessing error, or incorrect output inducing a compile-time error,
  44. does not solve the problem of constrained input for preprocessor metaprogramming. Often it is impossible
  45. to determine if the input meets the constraints which the preprocessor metaprogrammer places on it and
  46. documents. Certain preprocessing tokens cannot be checked reliably for particular values, or a range of
  47. values, without the checking mechanism itself creating a preprocessing error or undefined behavior.
  48. This does not mean that one should give up attempting to check macro input constraints. If it can be done
  49. I see the value of such checks and a number of VMD macros, discussed later, are designed as preprocessing
  50. input constraint checking macros. But the most important thing when dealing with macro input constraints is
  51. that they should be carefully documented, and that the programmer should know that if the constraints are
  52. not met either preprocessing errors or incorrect macro results could be the results.
  53. The VMD library, in order to present more preprocessor programming functionality and
  54. flexibility, allows that erroneous results could occur if certain input constraints are not met, whether the
  55. erroneous results are preprocessing errors or incorrect output from a VMD macro. At the same time the VMD does
  56. everything that the preprocessor is capable of doing to check the input constraints, and carefully documents
  57. for each macro in the library what the input for each could be in order to avoid erroneous output.
  58. Documented macro input constraints are just as valid in the preprocessor as
  59. compile-time/run-time constraints are valid in C++, even if the detection of such constraints
  60. and/or the handling of constraints that are not met are far more difficult,
  61. if not impossible, in the preprocessor than in the compile-time/run-time processing of C++.
  62. The VMD library uses constraints for most of it macros and the documentation for those macros
  63. mentions the constraints that apply in order to use the macro.
  64. [endsect]