Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>The idea is coined "X-Macro". Some definitions won't include your particular example (X-macros generally are a bit more involved, with a file being included), but any relevant info. about this will fall under that term when searching.</p> <p>As <a href="https://stackoverflow.com/users/962089/chris">chris</a> mentioned in the comments, Boost.Preprocessor uses this idea to great effect. Popular uses are: <code>BOOST_PP_REPEAT</code>, <code>BOOST_PP_LIST_FOR_EACH</code>, and most powerfully: <code>BOOST_PP_ITERATE</code>.</p> <p><code>BOOST_PP_ITERATE</code> is a "true" X-Macro; including a single file is expands to something dependent on a macro defined just prior. I show a more "proper" skeleton framework in this <a href="https://stackoverflow.com/a/12963911/87234">other answer</a>, but an example would be:</p> <pre><code>// in xyz_data.def DEFINE_XYZ(foo, 1, "Description A") DEFINE_XYZ(bar, 5, "Description B") DEFINE_XYZ(baz, 7, "Description C") </code></pre> <p>Then later when I just want column 1 I can do:</p> <pre><code>#define DEFINE_XYZ(name, number, desc) some_func(name) #include "xyz_data.def" </code></pre> <p>And somewhere else where I want to generate some function for each one, I can do:</p> <pre><code>#define DEFINE_XYZ(name, number, desc) \ int BOOST_PP_CAT(get_number_for_, name)() \ { \ std::clog &lt;&lt; "Getting number, which is: " desc &lt;&lt; std::endl; \ \ return number; \ } #include "xyz_data.def" </code></pre> <p>You can then generate an enum where the name equals the number, etc.</p> <p>The power is that when I want to add a new xyz, I just add it in one spot and it magically shows up everywhere it needs to be. I have done something like this in a very large codebase to keep some bookmarking data in one central place, but the various attributes were used differently in various locations.</p> <p>Note that there is often no way around this; what I have are <em>syntactically different</em>, so no other language feature will generalize it for me to that level, only macros. Macros are not evil.</p> <p>What you have is effectively an X-macro where the .def file is self-contained enough to be a <code>#define</code>. In other words, <code>#include "xyz_data.def"</code> is just <code>TOP_LEVEL</code>.</p> <p>There is only one large downside to this, and ironically it's not the use of X-macros themselves but the effect they have on C and C++ compilers. The problem is that the preprocessor has allowed us to change the preprocessed result of a file every time its included, even if the file contents are <em>exactly the same</em>.</p> <p>You may have heard that C and C++ are slow to compile compared to modern languages, this is one of the reasons why. It has no proper module/packaging system, just ad-hoc inclusion of other files. And we just learned, <em>in general this cannot be avoided</em>. Oops. (That said, compilers are smart and will note when you have include guards around a file, for example, and avoid processing it multiple times. But this is situational.)</p> <p>That said, using X-Macros themselves shouldn't be a huge contributor to the compilation time of a real program. It's just that their mere potential existence reaches out into the real word and screws with compiler's heads.</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload