【问题标题】:Avoid macro to be usable from client code避免宏在客户端代码中可用
【发布时间】:2013-08-17 22:16:21
【问题描述】:

我目前正在开发一个仅包含标头的库,并且我希望能够使用一些宏,而无需从客户端代码中使用它们。示例:

// library_header1.h

#define MACRO_NUMBER_1(__X__) doSomethingWith(__X__) // etc...

class LibraryClass1
{
    // We'll use the macro somewhere in here.
};

现在,如果我包含 library_header1.h,我就可以使用 MACRO_NUMBER_1。有什么办法可以避免吗?

【问题讨论】:

  • #undef 似乎工作正常,但我也想知道是否有任何方式未定义宏(以便自动完成/智能感知不显示它们)。
  • 您正在以源代码形式提供您的库。您不能希望隐藏实现。是否显示宏取决于 Intellisense 实现。对于 Microsoft 的编译器,您可以检查使用 #pragma push_macro/pop_macro 是否对 Intellisense 实现有任何影响。
  • 您可以在 Visual Studio 中使用预构建后构建事件来仅在编译期间启用宏并避免智能感知。检查msdn.microsoft.com/en-us/library/vstudio/42x5kfw4.aspx

标签: c++ c-preprocessor


【解决方案1】:

其他人已经提到了#undef,但是如果您有很多宏需要取消定义并且需要在很多标题中使用它们怎么办?这种情况可以通过定义和取消定义包含指定标题的宏和以下宏来处理。例如:

// temp-macros.h
#if defined(OUTER)
#  define MACRO x
#  include OUTER
#  undef MACRO
#  undef OUTER
#endif

想法是从需要宏的标头设置OUTER,包含temp-macros.h并在第二个包含中使用宏:

// macro-use.h
#if !defined(OUTER)
#  define OUTER "macro-use.h"
#  include "temp-macros.h"
#elif !defined(INCLUDED_MACRO_USE)
#  define INCLUDED_MACRO_USE
void use(int MACRO) { /*...*/ }
#endif

当然,这个例子只使用了一个微不足道的宏,但如果有更多的宏并且它们更复杂,这种方法可能会很有用。

【讨论】:

    【解决方案2】:

    为防止库用户访问宏 - 当您知道不再需要宏时,可以输入 #undef

    如果您想阻止智能感知/自动完成功能看到您的宏,您可以尝试通过跳过宏定义来欺骗它。通常你可以这样做:

    • 设置您的编译项目(可视化解决方案、makefile...),以便您传递一个额外的“标识”宏。类似-DIAMCOMPILING
    • 使用#ifdef IAMCOMPILING ... #endif 保护您的宏定义

    您的 IDE 很可能无法识别 IAMCOMPILING 并跳过您的宏定义。

    但请注意,当您实际使用头文件中的宏时,IDE 会感到困惑,并且会标记一些不存在的错误。

    【讨论】:

      【解决方案3】:

      虽然它不会阻止宏被 IDE 注意到,但如果您对宏使用不寻常的前缀,它就不太可能与用户想要做的事情发生冲突,从而减少冒犯性.它可能不是理想的解决方案,但在宏前面加上 CCC 或 XWX 或其他普通程序员不太可能使用的东西可能会有所帮助。

      (或者,不使用宏总是可行的解决方案!)

      【讨论】:

      • 好主意。但是,使用例如 Visual Assist 的 Acronyms 时,带有异常字符组合的前缀将失败。突然间,你所有不寻常的组合都将成为潜在的用户输入。另外,我很高兴看到正确评估__LINE__ 的非宏版本。有时,宏是必需品。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-05-17
      • 1970-01-01
      • 2015-03-02
      • 1970-01-01
      • 1970-01-01
      • 2018-10-26
      • 1970-01-01
      相关资源
      最近更新 更多