vmd_empty.qbk 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383
  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_test_empty Emptiness]
  8. [heading Passing empty arguments]
  9. It is possible to pass an empty argument to a macro.
  10. The official terminology for this in the C++ standard is an argument
  11. "consisting of no preprocessing tokens".
  12. Let us consider a number of cases without worrying too much
  13. what the macro output represents.
  14. Consider these two function-like macros:
  15. #define SMACRO() someoutput
  16. #define EMACRO(x) otheroutput x
  17. The first macro takes no parameters so invoking it must always be done by
  18. SMACRO()
  19. and passing any arguments to it would be invalid.
  20. The second macro takes a single parameter. it can be evoked as
  21. EMACRO(somedata)
  22. but it also can be invoked as
  23. EMACRO()
  24. In the second invocation of EMACRO we are passing an empty argument to the macro.
  25. Similarly for any macro having 1 or more parameters, an empty argument
  26. can be validly passed for any of the parameters, as in
  27. #define MMACRO(x,y,z) x y z
  28. MMACRO(1,,2)
  29. An empty argument is an argument even if we are passing nothing.
  30. Because an empty argument can be passed for a given parameter of
  31. a macro does not mean one should do so. Any given macro will specify what each
  32. argument to a macro should represent, and it is has normally been very rare to encounter
  33. a macro which specifies that an empty argument can logically be passed for a given
  34. argument. But from the perspective of standard C++ it is perfectly valid to
  35. pass an empty argument for a macro parameter.
  36. The notion of passing empty arguments can be extended to passing empty data which
  37. "consists of no preprocessing tokens" in slightly more complicated situations.
  38. It is possible to pass empty data as an argument to a variadic macro in the form of
  39. variadic macro data, as in
  40. #define VMACRO(x,...) x __VA_ARGS__
  41. invoked as
  42. VMACRO(somedata,)
  43. Here one passes empty data as the variadic macro data and it is perfectly valid C++.
  44. Please notice that this different from
  45. VMACRO(somedata)
  46. which is not valid C++, prior to C++20, since something must be passed for the variadic argument.
  47. In C++20 the above invocation is valid and is exactly the same as in our previous example of
  48. 'VMACRO(somedata,)' where one passes empty data as the variadic macro data. Similarly one could
  49. invoke the macro as
  50. VMACRO(somedata,vdata1,,vdata3)
  51. where one is passing variadic macro data but an element in the variadic macro data is empty.
  52. Furthermore if we are invoking a macro which expects a Boost PP data type, such as
  53. a tuple, we could also validly pass empty data for all or part of the data in a tuple,
  54. as in
  55. #define TMACRO(x,atuple) x atuple
  56. TMACRO(somedata,())
  57. In this case we are passing a 1 element tuple
  58. where the single element itself is empty.
  59. or
  60. TMACRO(somedata,(telem1,,telem2,teleem3))
  61. In this case we are passing a 4 element tuple where
  62. the second element is empty.
  63. Again either invocation is valid C++ but it is not necessarily what the
  64. designed of the macro has desired, even if in both cases the macro designer
  65. has specified that the second parameter must be a tuple for the macro
  66. to work properly.
  67. [heading Returning emptiness]
  68. Similar to passing empty arguments in various ways to a macro,
  69. the data which a macro returns ( or 'generates' may be a better term )
  70. could be empty, in various ways. Again I am not necessarily promoting
  71. this idea as a common occurrence of macro design but merely pointing it
  72. out as valid C++ preprocessing.
  73. #define RMACRO(x,y,z)
  74. RMACRO(data1,data2,data3)
  75. It is perfectly valid C++ to return "nothing" from a macro invocation.
  76. In fact a number of macros in Boost PP do that based on the preprocessor
  77. metaprogramming logic of the macro, and are documented as such.
  78. Similarly one could return nothing as part or all of a Boost PP
  79. data type or even as part of variadic macro data.
  80. #define TRETMACRO(x,y,z) ()
  81. #define TRETMACRO1(x,y,z) (x,,y,,z)
  82. #define VRETMACRO(x,y,z) x,,y,,z
  83. Here again we are returning something but in terms of a Boost PP
  84. tuple or in terms of variadic data, we have elements which are empty.
  85. [heading Emptiness in preprocessor metaprogramming]
  86. In the examples given above where "emptiness" in one form of another
  87. is passed as arguments to a macro or returned from a macro, the examples
  88. I have given were created as simplified as possible to illustrate my points.
  89. In actual preprocessor metaprogramming, using Boost PP, where complicated logic
  90. is used to generate macro output based on the arguments to a macro, it might be
  91. useful to allow and work with empty data if one were able to test for the fact
  92. that data was indeed empty.
  93. [heading Testing for empty data]
  94. Currently Boost PP has an undocumented macro for testing whether
  95. a parameter is empty of not, written without the use of variadic
  96. macros. The macro is called BOOST_PP_IS_EMPTY. The macro is by its nature flawed,
  97. since there is no generalized way of determining whether or not a
  98. parameter is empty using the C++ preprocessor prior to C++20. But the macro will
  99. work given input limited in various ways or if the input is actually empty.
  100. Paul Mensonides, the developer of Boost PP and the BOOST_PP_IS_EMPTY macro
  101. in that library, also wrote a better macro using variadic
  102. macros, for determining whether or not a parameter is empty or not, which
  103. he published on the Internet in response to a discussion about emptiness.
  104. This macro is also not perfect, since there is no perfect solution prior to C++20,
  105. but will work correctly with almost all input. I have adapted his code
  106. for VMD and developed my own very slightly different code.
  107. The macro is called [macroref BOOST_VMD_IS_EMPTY] and will return 1 if its input
  108. is empty or 0 if its input is not empty. The macro
  109. is a variadic macro which make take any input
  110. [footnote For VC++ 8 the input is not variadic data but a single parameter].
  111. [heading Macro Flaw with a standard C++ compiler]
  112. The one situation prior to C++20 where the macro does not work properly is if
  113. its input resolves to a function-like macro name or a sequence of preprocessor tokens ending with
  114. a function-like macro name and the function-like macro takes two or more parameters.
  115. Here is a simple example:
  116. #include <boost/vmd/is_empty.hpp>
  117. #define FMACRO(x,y) any_output
  118. BOOST_VMD_IS_EMPTY(FMACRO)
  119. BOOST_VMD_IS_EMPTY(some_input FMACRO)
  120. In the first case the name of a function-like macro is being passed to
  121. BOOST_VMD_IS_EMPTY while in the second case a sequence of preprocessing tokens is being
  122. passed to BOOST_VMD_IS_EMPTY ending with the name of a function-like macro.
  123. The function-like macro also has two ( or more ) parameters. In both the
  124. cases above a compiler error will result from the use of BOOST_VMD_IS_EMPTY.
  125. Please note that these two problematical cases are not the same as passing
  126. an invocation of a function-like macro name to BOOST_VMD_IS_EMPTY, as in
  127. #include <boost/vmd/is_empty.hpp>
  128. BOOST_VMD_IS_EMPTY(FMACRO(arg1,arg2))
  129. BOOST_VMD_IS_EMPTY(someinput FMACRO(arg1,arg2))
  130. which always works correctly, unless of course a particular function-like macro
  131. invocation resolves to either of our two previous situations.
  132. Another situation where the macro may not work properly is if the previously mentioned
  133. function-like macro takes a single parameter but creates an error when the argument
  134. passed is empty. An example of this would be:
  135. #define FMACRO(x) BOOST_PP_CAT(+,x C);
  136. When nothing is passed to FMACRO undefined behavior will occur since attempting to concatenate
  137. '+' to ' C' is UB in C++ preprocessor terms.
  138. So for a standard conforming compiler, prior to C++20, we have essentially two corner cases where
  139. the BOOST_VMD_IS_EMPTY does not work and, when it does not work it, produces a
  140. compiler error rather than an incorrect result. Essentially what is desired for maximum
  141. safety is that we never pass input ending with the name of a function-like macro name when
  142. testing for emptiness.
  143. [heading Macro Flaw with Visual C++]
  144. The VC++ preprocessor is not a standard C++ conforming preprocessor in at least two
  145. relevant situations to our discussion of emptiness. These situations combine to create
  146. a single corner case which causes the BOOST_VMD_IS_EMPTY macro to not work properly
  147. using VC++ when the input resolves to a function-like macro name.
  148. The first situation, related to our discussion of emptiness, where the VC++ preprocessor
  149. is not a standard C++ conforming preprocessor is that if a macro taking 'n' number of parameters is invoked
  150. with 0 to 'n-1' parameters, the compiler does not give an error, but only a warning.
  151. #define FMACRO(x,y) x + y
  152. FMACRO(1)
  153. should give a compiler error, as it does when using a C++ standard-conforming
  154. compiler, but when invoked using VC++ it only gives a warning
  155. and VC++ continues macro substitution with 'y' as a placemarker preprocessing token.
  156. This non-standard conforming action actually eliminates the case where BOOST_VMD_IS_EMPTY
  157. does not work properly with a standard C++ conforming compiler. But of course it has the
  158. potential of producing incorrect output in other macro processing situations unrelated
  159. to the BOOST_VMD_IS_EMPTY invocation, where a compiler error should occur.
  160. A second general situation, related to our discussion of emptiness, where the VC++ preprocessor
  161. is not a standard C++ conforming preprocessor is that the expansion of a macro works incorrectly
  162. when the expanded macro is a function-like macro name followed by a function-like macro invocation,
  163. in which case the macro re-expansion is erroneously done more than once. This latter case can be
  164. seen by this example:
  165. #define FMACRO1(parameter) FMACRO3 parameter()
  166. #define FMACRO2() ()
  167. #define FMACRO3() 1
  168. FMACRO1(FMACRO2)
  169. should expand to:
  170. FMACRO3()
  171. but in VC++ it expands to:
  172. 1
  173. where after initially expanding the macro to:
  174. FMACRO3 FMACRO2()
  175. VC++ erroneously rescans the sequence of preprocessing tokens more than once rather than
  176. rescan just one more time for more macro names.
  177. What these two particular preprocessor flaws in the VC++ compiler mean is that although
  178. BOOST_VMD_IS_EMPTY does not fail with a compiler error in the same case as with
  179. a standard C++ conforming compiler given previously, it fails by giving
  180. the wrong result in another situation.
  181. The failing situation is:
  182. when the input to BOOST_VMD_IS_EMPTY resolves to only a function-like macro
  183. name, and the function-like macro, when passed a single empty argument, expands to
  184. a Boost PP tuple, BOOST_VMD_IS_EMPTY will erroneously return 1 when using the Visual C++
  185. compiler rather than either give a preprocessing error or return 0.
  186. Here is an example of the failure:
  187. #include <boost/vmd/is_empty.hpp>
  188. #define FMACRO4() ( any_number_of_tuple_elements )
  189. #define FMACRO5(param) ( any_number_of_tuple_elements )
  190. #define FMACRO6(param1,param2) ( any_number_of_tuple_elements )
  191. BOOST_VMD_IS_EMPTY(FMACRO4) // erroneously returns 1, instead of 0
  192. BOOST_VMD_IS_EMPTY(FMACRO5) // erroneously returns 1, instead of 0
  193. BOOST_VMD_IS_EMPTY(FMACRO6) // erroneously returns 1, instead of generating a preprocessing error
  194. As with a standard C++ conforming compiler prior to C++20, we have a rare corner case where
  195. the BOOST_VMD_IS_EMPTY will not work properly, but unfortunately in this very
  196. similar but even rarer corner case with VC++, we will silently get an incorrect result
  197. rather than a compiler error.
  198. I want to reiterate that for all compilers prior to C++20 there is no perfect solution
  199. in C++ to the detection of emptiness even for a C++ compiler whose preprocessor is completely
  200. conformant, which VC++ obviously is not.
  201. [heading Testing emptiness in C++20 mode]
  202. A few compilers can currently operate in C++20 mode, by which I mean that you
  203. can pass a compiler flag when compiling with such a compiler which enforces the
  204. upcoming C++20 standard. One of the features of the C++20 standard is the
  205. addition of a preprocessor construct called __VA_OPT__. Because of the
  206. specification of how the __VA_OPT__ construct works in C++20, it is now possible
  207. to have the BOOST_VMD_IS_EMPTY macro work perfectly to test for emptiness without
  208. any of the flaws that exist in the macro for levels of the C++ standard before
  209. C++20. But the macro will only do a 100% reliable test for emptiness when the
  210. compiler is compiling in C++20 mode. For all levels of the C++ standard before
  211. C++20, such as C++98, C++03, C++11, C++14, and C++17, the testing for emptiness
  212. has the corner cases which prevent it from wroking perfectly which have already
  213. been discussed.
  214. Furthermore in C++20 mode it is possible that a compiler still does not yet
  215. support the __VA_OPT__ construct, even though it is part of the C++20 standard.
  216. Luckily it is possible to test whether or not a compiler supports the __VA_OPT__
  217. construct in C++20 mode, and the macro implementation of BOOST_VMD_IS_EMPTY
  218. does that before using the construct to provide a perfectly reliable
  219. implementation for testing emptiness.
  220. The result of all this is that when a compiler is compiling source using
  221. the C++20 standard, and supports the C++20 __VA_OPT__ preprocessor construct,
  222. the implementation provides a completely reliable way of testing for emptiness
  223. using the BOOST_VMD_IS_EMPTY macro. Otherwise the BOOST_VMD_IS_EMPTY macro
  224. has the corner cases previously discussed which make the macro less than
  225. 100% reliable in testing for emptiness. The good news of course is that
  226. more compilers will be implementaing the C++20 standard and more C++
  227. programmers will be using the C++20 standard to compile their code.
  228. The programmer may know whether the compiler is being used in C++20 mode
  229. from the command line parameters he passes to the compiler, and the programmer
  230. may know whether the compiler in C++20 mode supports the __VA_OPT__ construct
  231. of C++20 from the compiler's documentation. But from the preprocessor programming
  232. perspective it would be good to find out using a macro whether or not C++20 mode
  233. with the __VA_OPT__ construct is being used so that the BOOST_VMD_IS_EMPTY
  234. macro can be considered completely reliable in testing for emptiness. Such a macro
  235. does already exist in the Boost Preprocessor library, and it is called BOOST_PP_VARIADIC_HAS_OPT.
  236. You can read the documentation for this macro in the Boost Preprocessor library
  237. documentation, but I will give a quick rundown of how this works here. The macro
  238. is a function-like macro taking no parameters and returns 1 if the compiler
  239. is in C++20 mode and __VA_OPT__ is supported, otherwise returns 0. The header
  240. file needed to invoke the macro as BOOST_PP_VARIADIC_HAS_OPT() is included as:
  241. #include <boost/preprocessor/variadic/has_opt.hpp>
  242. The programmer does not have to be compiling in C++20 mode to invoke the
  243. BOOST_PP_VARIADIC_HAS_OPT macro. When the programmer is not in C++20 mode invoking
  244. the macro always returns 0. When the programmer is in C++20 mode invoking
  245. the macro returns 1 when the __VA_OPT__ construct is supported and returns 0
  246. when the __VA_OPT__ construct is not supported. It does this latter step through
  247. clever preprocessor programming.
  248. [heading Macro Flaw conclusion]
  249. With all of the above mentioned, the cases where BOOST_VMD_IS_EMPTY will work
  250. incorrectly are very small, even with the erroneous VC++ preprocessor,
  251. and I consider the macro worthwhile to use since it works correctly with the vast
  252. majority of possible preprocessor input, and always works correctly in C++20
  253. mode with __VA_OPT__ preprocessor support.
  254. The case where it will not work, with both a C++ standard conforming preprocessor or
  255. with Visual C++, occurs when the name of a function-like macro is part of the input
  256. to BOOST_VMD_IS_EMPTY. Obviously the macro should be used by the preprocessor
  257. metaprogrammer when the possible input to it is constrained to eliminate the erroneous
  258. case.
  259. Furthermore, since emptiness can correctly be tested for in nearly every situation, the
  260. BOOST_VMD_IS_EMPTY macro can be used internally when the preprocessor metaprogrammer wants to return data
  261. from a macro and all or part of that data could be empty.
  262. Therefore I believe the BOOST_VMD_IS_EMPTY macro is quite useful, despite the corner case flaws
  263. which makes it imperfect. Consequently I believe that the preprocessor metaprogrammer
  264. can use the concept of empty preprocessor data in the design of his own macros.
  265. [heading Using the macro]
  266. The macro BOOST_VMD_IS_EMPTY is used internally throughout VMD and macro programmers
  267. may find this macro useful in their own programming efforts despite the slight flaw
  268. in the way that it works in pre C++20 mode.
  269. You can use the general header file:
  270. #include <boost/vmd/vmd.hpp>
  271. or you can use the individual header file:
  272. #include <boost/vmd/is_empty.hpp>
  273. for the BOOST_VMD_IS_EMPTY macro.
  274. [endsect]