emptiness.html 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211
  1. <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
  2. <html>
  3. <head>
  4. <meta content="text/html; charset=windows-1252"
  5. http-equiv="content-type">
  6. <title>emptiness.html</title>
  7. <link rel="stylesheet" type="text/css" href="../styles.css">
  8. <style>
  9. u { font-weight: normal; text-decoration: none; }
  10. </style>
  11. </head>
  12. <body>
  13. <h4>Passing nothing</h4>
  14. <div> Although rarely desirable it has always been legal in C++ to
  15. pass nothing, aka no preprocessor tokens, as an argument when
  16. invoking a macro, whether the equivalent parameter be a regular
  17. parameter or a variadic one. </div>
  18. <div class="code">
  19. <pre> #define SOME_MACRO(Parameter1,Parameter2) macro expansion using Parameter1 and Parameter2
  20. #define SOME_VARIADIC_MACRO(Parameter1,...) macro expansion using Parameter1 and __VA_ARGS__
  21. SOME_MACRO(a,b) // Normal
  22. SOME_MACRO(a,) // Legal, second argument is empty
  23. SOME_MACRO(,b) // Legal, first argument is empty
  24. SOME_MACRO(a) // Preprocessor error, passing the wrong number of arguments
  25. SOME_VARIADIC_MACRO(a,b,c,d) // Normal
  26. SOME_VARIADIC_MACRO(a,) // Legal, variadic argument is empty
  27. SOME_VARIADIC_MACRO(,b,c,d) // Legal, first argument is empty
  28. SOME_VARIADIC_MACRO(a) /* Preprocessor error in standard below C++20 level,
  29. but in C++20 exactly equivalent to SOME_VARIADIC_MACRO(a,) */</pre>
  30. </div>
  31. <h4>Expanding to nothing</h4>
  32. <div> Given certain arguments a macro might expand to nothing, aka
  33. no preprocessor tokens. This may happen more than in the previous
  34. case of an argument to a macro being nothing because the expansion
  35. of a macro is often used to initialize some C++ construct, and C++
  36. has some places where a part of a compile-time construct can be
  37. empty. However a macro which expands to nothing rarely occurs when
  38. that macro's expansion is used as an argument to another macro
  39. because we would again have a macro where we are passing nothing
  40. as an argument. </div>
  41. <div class="code">
  42. <pre> #define ANOTHER_MACRO(Parameter1,Parameter2) /* expands to nothing when Parameter1 and Parameter2
  43. are numbers, otherwise expands to some preprocessing
  44. token, such as '1' */
  45. int another_int = { ANOTHER_MACRO(x,y) }; // ANOTHER_MACRO Expands to 1
  46. int some_int = { ANOTHER_MACRO(1,2) }; // ANOTHER_MACRO Expands to nothing
  47. SOME_MACRO(ANOTHER_MACRO(x,y),z) // Normal, ANOTHER_MACRO Expands to 1
  48. SOME_MACRO(ANOTHER_MACRO(1,2),z) // Legal, first argument is empty as ANOTHER_MACRO Expands to nothing</pre>
  49. </div>
  50. <h4>Emptiness defined</h4>
  51. <div> Passing nothing as a macro argument or a macro expanding to
  52. nothing I term as 'emptiness', as 'nothing' is too amorphous a
  53. term which can be used in too many other contexts for my liking.
  54. In the vast majority of cases when designing a macro for use
  55. emptiness is not a part of such a design, and passing emptiness as
  56. an argument or expanding to emptiness is not anything that someone
  57. writing a macro takes into account when he explains to other
  58. programmers how a macro should be used.<br>
  59. <br>
  60. Other than the fact that macros are generally created so that some
  61. actual preprocessor data of a particular kind needs to be passed
  62. as arguments or gets generated as part of macro expansion when a
  63. macro is invoked, there is another very good reason why working
  64. with emptiness is not part of a macro's design: there has been no
  65. perfectly fail-safe way to test for emptiness during macro
  66. expansion, whether it be in creating macros using just the
  67. facilities of the C++ standard or using a 3rd party library, such
  68. as this Boost preprocessor library. When I say 'fail-safe' I mean
  69. that there has always been some argument input, no matter how
  70. small the number of potential cases, where a macro designed to
  71. test whether or not the preprocessor data passed to it as an
  72. argument when the macro is invoked is actually empty fails in some
  73. way, with the failure normally occurring as a preprocessor error.<br>
  74. <br>
  75. Of course this does not mean that the best macro designed to test
  76. for emptiness will not work correctly the vast majority of the
  77. time. It only means that there has been no guarantee that such a
  78. macro will work correctly all 100% of the time. Nonetheless there
  79. have been uses of testing for emptiness, when a macro documents
  80. what a particular argument should generally consist of, even if
  81. the test is not guaranteed to work 100% of the time if particular
  82. unexpected argument data does get passed. </div>
  83. <h4>A C++20 solution for testing for emptiness</h4>
  84. <div> The C++ standard committee recognized, in the upcoming
  85. specification for the C++20 standard, that a way of testing
  86. whether variadic data is empty or not in the expansion of a
  87. variadic macro would be very useful when designing certain types
  88. of macros. Because of this the C++20 standard added a preprocessor
  89. construct which could do this in a certain way for variadic data
  90. in the expansion of a variadic macro. The construct is called
  91. __VA_OPT__, as in '__VA_OPT__ ( prepocessing tokens )' specified
  92. in the replacement list of a variadic macro. <br>
  93. <br>
  94. The way that the __VA_OPT__ constructs works is that if the
  95. variadic arguments to the variadic macro are empty or expand to
  96. emptiness then the __VA_OPT__ construct and its enclosed
  97. preprocessing token data expands to nothing, or in C++ terms "a
  98. single placemarker preprocessing token". Otherwise the __VA_OPT__
  99. construct expands to its enclosed preprocessing tokens. A further,
  100. possibly unintended, upshot of adding the __VA_OPT__ construct to
  101. C++20 is that it is now possible to create a variadic macro which
  102. is 100% reliable in testing for emptiness whenever a compiler
  103. supports the __VA_OPT__ construct in its compilation of
  104. preprocessor code.<br>
  105. <br>
  106. For such a macro to always work which tests for emptiness the code
  107. must know when the __VA_OPT__ construct is available. It is not
  108. enough to know that a compiler is working at the C++20 level,
  109. since as all C++ programmers know an adherence to a C++ standard
  110. level never guarantees that a particular compiler supports every
  111. aspect of that level. Happily there is a way to test whether a
  112. compiler supports the __VA_OPT__ construct as long as the compiler
  113. supports variadic macros, and that way has been openly published
  114. on the Internet, although the actual macro code would not have
  115. been hard to create even if it had not publicly appeared. This
  116. library uses that code to test for __VA_OPT__ as a necessary
  117. prelude for creating a variadic macro which is 100% reliable in
  118. testing for emptiness.<br>
  119. <br>
  120. The Boost Preprocessor macro for testing whether the __VA_OPT__
  121. construct is supported during compilation is called
  122. BOOST_PP_VARIADIC_HAS_OPT, which is a function-like macro taking
  123. no parameters and returning 1 if the __VA_OPT__ construct is
  124. supported and 0 if it is not. The macro only returns 1 when
  125. variadic macros are supported, when the compiler is at the C++20
  126. level, and when the __VA_OPT__ construct can be used according to
  127. the C++20 standard. In particular the macro needs the compiler to
  128. be working at the C++20 level despite the fact that at least one
  129. major compiler supports the __VA_OPT__ construct in some of its
  130. latest releases even when the compiler is being used at a C++
  131. standard level below that of C++20. The reason this Boost
  132. preprocessor library requires the C++20 level is because that same
  133. major compiler can produce a warning, or even an error, when it
  134. even sees a macro using the __VA_OPT__ construct at a level below
  135. C++20, even though it supports it, if other compiler options
  136. requiring strict adherence to the level of the C++ standard being
  137. used are passed on the command line. So taking a conservative
  138. approach the BOOST_PP_VARIADIC_HAS_OPT macros requires compilation
  139. at the C++20 level, along with variadic macro support, along with
  140. the testing code expanding to 1, in order to specify that
  141. __VA_OPT__ is supported.<br>
  142. <br>
  143. The actual Boost Preprocessor library for testing for emptiness in
  144. C++20 mode is called BOOST_PP_CHECK_EMPTY. The macro is a variadic
  145. macro with a single variadic parameter. The macro only exists if
  146. our previous macro for testing for __VA_OPT__, called
  147. BOOST_PP_VARIADIC_HAS_OPT, expands to 1 when invoked as
  148. BOOST_PP_VARIADIC_HAS_OPT(). If BOOST_PP_VARIADIC_HAS_OPT()
  149. expands to 0 the BOOST_PP_CHECK_EMPTY macro does not exist at all
  150. in this library. The input to the BOOST_PP_CHECK_EMPTY macro can
  151. be any variadic data. If the data passed to the macro is empty, or
  152. if the data passed to the macro is not empty but when the data
  153. itself is expanded it is empty, the macro returns 1, otherwise it
  154. returns 0. The macro works 100% of the time and is completely
  155. reliable no matter what preprocessor data is passed to it. But of
  156. course it only works when compiling at the C++20 level with the
  157. __VA_OPT__ construct supported by the compiler. It solves an old
  158. problem that it has never been possible, prior to C++20, to
  159. provide a 100% reliable implementation of a macro which tests for
  160. emptiness in C++.<br>
  161. <br>
  162. Along with the valuable BOOST_PP_CHECK_EMPTY macro the Boost
  163. Preprocessor library has also added a more flexible, if slightly
  164. verbose, alternative to the __VA_OPT__ construct, which works by
  165. using the ability of BOOST_PP_CHECK_EMPTY to reliably test for
  166. emptiness. This macro is called BOOST_PP_VA_OPT and allows the
  167. programmer to specify preprocessing tokens for expansion both when
  168. the variadic data is <b>not</b> empty and when the variadic data
  169. is empty. This improves on the __VA_OPT__ construct's ability to
  170. specify preprocessing tokens for expansion only when the variadic
  171. data is not empty. Like BOOST_PP_CHECK_EMPTY, which it uses, the
  172. BOOST_PP_VA_OPT macro only exists when BOOST_PP_VARIADIC_HAS_OPT()
  173. expands to 1. You can read further about how this macro works as
  174. an alternative to the C++20 __VA_OPT__ construct in the
  175. documentation for the macro itself.<br>
  176. <br>
  177. Eventually more C++ compilers will support C++20 and the
  178. __VA_OPT__ construct and more programmers will use compilers at
  179. the C++20 level. At that point the macro BOOST_PP_CHECK_EMPTY can
  180. be used reliably for testing emptiness in preprocessor data in
  181. macro code by all those programmers. The BOOST_PP_VA_OPT macro
  182. serves as a useful example of such use. This does not mean that
  183. designing macros with emptiness in mind needs to be done, much
  184. less considered, but that the possibility of doing so with
  185. complete reliability will be there if needed by the macro
  186. programmer. Along with the __VA_OPT__ construct as mandated by the
  187. C++20 standard the BOOST_PP_CHECK_EMPTY and BOOST_PP_VA_OPT macros
  188. add three more tools in the arsenal of macro programming, which is
  189. a good thing, while programmers who wanted to ignore any dealing
  190. with emptiness in macro code can continue to do so. </div>
  191. <b>See</b> <b>Also</b><br>
  192. <ul>
  193. <li><a href="../ref/variadic_has_opt.html">BOOST_PP_VARIADIC_HAS_OPT</a></li>
  194. <li><a href="../ref/check_empty.html">BOOST_PP_CHECK_EMPTY</a></li>
  195. <li><a href="../ref/va_opt.html">BOOST_PP_VA_OPT</a><br>
  196. </li>
  197. </ul>
  198. <hr size="1">
  199. <div style="margin-left: 0px;"> <i>© Copyright Edward Diener 2019</i>
  200. </div>
  201. <div style="margin-left: 0px;">
  202. <p><small>Distributed under the Boost Software License, Version
  203. 1.0. (See accompanying file <a
  204. href="../../../../LICENSE_1_0.txt">LICENSE_1_0.txt</a> or
  205. copy at <a href="http://www.boost.org/LICENSE_1_0.txt">www.boost.org/LICENSE_1_0.txt</a>)</small></p>
  206. </div>
  207. </body>
  208. </html>