简体   繁体   English

宏和视觉 C++

[英]Macros and Visual C++

I'm trying to get a better understanding of what place (if any) Macros have in modern C++ and Visual C++, also with reference to Windows programming libraries: What problem (if any) do Macros solve in these situations that cannot be solved without using them?我试图更好地了解宏在现代C++ 和 Visual C++ 中的位置(如果有),还参考 Windows 编程库:在这些情况下无法解决的问题是什么(如果没有)使用它们?

I remember reading about Google Chrome's use of WTL for Macros (amonst other things) from this blog post , and they are also used in MFC - here is an example of a Macro from that blog post I'd like explained in a superb amount of detail if possible:我记得从这篇博客文章中读到了谷歌浏览器对宏的 WTL 使用(除其他外),它们也用于 MFC - 这是该博客文章中的一个宏示例,我想用大量的解释如果可能,请详细说明:

// CWindowImpl
BEGIN_MSG_MAP(Edit)
  MSG_WM_CHAR(OnChar)
  MSG_WM_CONTEXTMENU(OnContextMenu)
  MSG_WM_COPY(OnCopy)
  MSG_WM_CUT(OnCut)
  MESSAGE_HANDLER_EX(WM_IME_COMPOSITION, OnImeComposition)
  MSG_WM_KEYDOWN(OnKeyDown)
  MSG_WM_LBUTTONDBLCLK(OnLButtonDblClk)
  MSG_WM_LBUTTONDOWN(OnLButtonDown)
  MSG_WM_LBUTTONUP(OnLButtonUp)
  MSG_WM_MBUTTONDOWN(OnNonLButtonDown)
  MSG_WM_MOUSEMOVE(OnMouseMove)
  MSG_WM_MOUSELEAVE(OnMouseLeave)
  MSG_WM_NCCALCSIZE(OnNCCalcSize)
  MSG_WM_NCPAINT(OnNCPaint)
  MSG_WM_RBUTTONDOWN(OnNonLButtonDown)
  MSG_WM_PASTE(OnPaste)
  MSG_WM_SYSCHAR(OnSysChar)  // WM_SYSxxx == WM_xxx with ALT down
  MSG_WM_SYSKEYDOWN(OnKeyDown)
END_MSG_MAP()

I've read these articles to do with Macros on MSDN but am trying to also pick up best practices for writing or avoiding Macros and where/when to use them.我已经在 MSDN 上阅读了这些与宏有关的文章,但我也在尝试学习编写或避免宏以及在何处/何时使用它们的最佳实践。

All of those Macros are defined in public sdk header files, so you can go read what they do yourself if you want.所有这些宏都在公共 sdk header 文件中定义,因此您可以 go 阅读他们自己做的事情。 Basically what is happening here is you're generating a WndProc function using Macros.基本上这里发生的是您正在使用宏生成 WndProc function。 Each MSG_WM_* entry is a case statement that handles the given window message by translating its arguments from wParam and lParam into their original types and calling a helper function (which you then get to go implement) that takes those types as arguments (if appropriate—some window messages have 0 or 1 arguments). Each MSG_WM_* entry is a case statement that handles the given window message by translating its arguments from wParam and lParam into their original types and calling a helper function (which you then get to go implement) that takes those types as arguments (if appropriate—一些 window 消息有 0 或 1 个参数)。

In my opinion all this is crap.在我看来,这一切都是废话。 You're trading off having to write a bunch of boiler-plate up front but in exchange you make it much harder to debug later.你不得不预先编写一堆样板,但作为交换,你使以后的调试变得更加困难。 Macros don't have much of a place in my modern programming world, other than to check if they are defined or not.宏在我的现代编程世界中没有太多的位置,除了检查它们是否被定义。 Macros that do flow control, or assume specific local variables are always defined, etc, make me quite unhappy.做流量控制的宏,或者假设特定的局部变量总是被定义的,等等,让我很不高兴。 Especially when I have to debug them.特别是当我必须调试它们时。

Peter, you might as well ask if vi or EMACS is the better editor.彼得,你不妨问问 vi 还是 EMACS 是更好的编辑器。 (EMACS, by the way.) There are a lot of people who think the C preprocessor is a horrible idea; (顺便说一下,EMACS。)很多人认为 C 预处理器是一个可怕的想法。 Stroustrup and Jim Gosling among them.其中包括 Stroustrup 和 Jim Gosling。 That's why Java has no preprocessor, and there are innumerable things Stroustrup put into C++, from const to templates, to avoid using the preprocessor.这就是为什么 Java 没有预处理器的原因,并且 Stroustrup 在 C++ 中放入了无数的东西,从const到模板,以避免使用预处理器。

There are other people who find it convenient to be able to add a new language, as in that code.还有其他人发现添加新语言很方便,就像在该代码中一样。

If you read the original Bourne shell code, you'll find it looks like如果您阅读原始 Bourne shell 代码,您会发现它看起来像

IF a == b THEN
   do_something();
   do_more();
ELSE
   do_less();
FI

Steve Bourne basically used macros to give it an Algol68-like look (that being the Really Cool Language then.) It could be very difficult to work with for anyone but Steve Bourne. Steve Bourne 基本上使用宏来赋予它类似 Algol68 的外观(那是当时非常酷的语言。)除了 Steve Bourne 之外的任何人都很难使用它。

Then have a look at the Obfuscated C contest, where some of the most amazing obfuscations take advantage of the #define .然后看看 Obfuscated C 竞赛,其中一些最令人惊叹的混淆利用了#define

Personally, I don't mind too much, although that example is a little daunting (how do you debug that?) But doing that kind of thing is working without a net;就个人而言,我不太介意,虽然那个例子有点令人生畏(你如何调试它?)但是做那种事情是没有网络的; there aren't many Wallendas out there.那里没有多少瓦伦达人。

(The question is kind of fragmented, but ignoring the Windows part): (这个问题有点支离破碎,但忽略了 Windows 部分):

X-Macros use the preprocessor to avoid code duplication. X-Macros使用预处理器来避免代码重复。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM