(评论)
(comments)

原始链接: https://news.ycombinator.com/item?id=43472143

一个Hacker News的帖子讨论了C++中的“X宏”模式,这是一种利用预处理器进行代码生成的技巧。原文介绍了这种模式,评论者提出了改进建议,例如使用描述性宏名、使用`#undef`避免命名空间污染以及使用`#ifndef`进行错误处理。 一些用户称赞X宏的简洁性、与构建过程的集成以及与IDE特性(例如跳转到定义)的兼容性。另一些用户承认其有用性,但更倾向于使用外部代码生成,原因是担心宏的复杂性。然而,外部代码生成的缺点包括构建复杂性增加、维护开销以及潜在的IDE兼容性问题。 该帖子还涉及X宏的历史背景及其与Rust声明式宏的相似之处。最后,一位用户提到一个实际应用:使用X宏生成枚举和相应的字符串表,确保两者之间的一致性和对齐。


原文
Hacker News new | past | comments | ask | show | jobs | submit login
My Favorite C++ Pattern: X Macros (2023) (danilafe.com)
9 points by ibobev 28 minutes ago | hide | past | favorite | 8 comments










Some minor tweaks to what the author shows to make it even better.

Give the macro a more descriptive name. For their example, call it GLOBAL_STRING instead of X. I think this helps make things clearer.

#undef the macro at the end of the header. That removes one line of boilerplate from every use of the header.

Use #ifndef at the top of the header and emit a nice error if the macro isn't defined. This will make it easier to understand what's wrong if you forget the #define or misspell the macro.



X Macros are a classic C++ pattern. Less known than some of the more popular techniques like curiously recurring template pattern, but still quite common in large codebases.

(Although... it is a neat trick, but... It is kind of mostly useful because C++ macros are not very powerful. If they were more powerful, most uses of X Macros could be replaced by just having a single macro do all of the magic.)

I recently saw something I hadn't seen before in a similar vein. There's a million different bin2c generators, and most of them will generate a declaration for you. However, I just saw a setup where the bin2c conversion just generates the actual byte array text, e.g. "0x00, 0x01, ..." so that you could #include it into whatever declaration you want. Of course, this is basically a poor man's #embed, but I found it intriguing nonetheless. (It's nice that programming languages have been adding file embedding as a first-class feature. This really simplifies a lot of stuff and removes the need to rely on more complex solutions for problems that don't really warrant them.)



It is a clever trick. Very useful in C also, maybe more than in C++.

It can be overused, though.

Kind of works like Rust declarative macros (`macro_rules!`) in that it is often used to repeat and expand something common across an axis of things that vary.

It's funny that the simple name X Macros has stuck and is a de facto standard. E.g. https://en.wikipedia.org/wiki/X_macro suggests they date to the 1960s.



I understand the use case of this, but when I see it I always wonder if, and think I would prefer, some external code generation step instead rather than falling back on macros in the preprocessor. Like an external script or something.


Now you have a additional stage in your build, a bunch of new code to maintain, and either a bespoke language embedded in your standard C++ or a bunch of code emitting C++ separately from the code it logically belongs with.

Compare with a solution that's 100% standard C++, integrates into your build with zero work, can be immediately understood by anyone reasonably skilled in the language, and puts the "generated" code right where it belongs.



IDEs understand preprocessor macros, so IDE features (jump2def, etc) work with this. IDEs also can expand the macro invocations. So, I prefer the macros when possible :-).


External codegen introduces a lot of friction in random places. Like how your editor can no longer understand the file before you start building. Or how it can go out of date with respect to the rest of your code until you build. If you can do it with a macro it tends to work better than codegen in some ways.


I hate X-Macros, but they're very useful in some situations. We use them to generate an enum of error values and also a string table of those names. (Unlike two separate tables, the X macro version is guaranteed to be the exact correct length / values align with the corresponding string.)






Join us for AI Startup School this June 16-17 in San Francisco!


Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact



Search:
联系我们 contact @ memedata.com