C++核心准则ES.30: 不要使用宏进行程序中的文本操作

ES.30: Don't use macros for program text manipulation

ES.30: 不要使用宏进行程序中的文本操作

 

Reason(原因)

Macros are a major source of bugs. Macros don't obey the usual scope and type rules. Macros ensure that the human reader sees something different from what the compiler sees. Macros complicate tool building.

宏是错误的主要来源之一。宏不会遵守通常的范围和类型准则。宏可以为人提供一个和编译器视角有些不同的视角。宏让工具构建变得更复杂。

 

Example, bad(反面示例)

#define Case break; case   /* BAD */

This innocuous-looking macro makes a single lower case c instead of a C into a bad flow-control bug.

这个看起来无害的宏在将大写C替换为小写c时引入了程序流控制错误。

 

Note(注意)

This rule does not ban the use of macros for "configuration control" use in #ifdefs, etc.

本准则没有禁止使用宏(如#ifdef等)进行配置控制。

In the future, modules are likely to eliminate the need for macros in configuration control.

将来,模块功能应该可以消除宏在配置控制方面的用途。

 

Note(注意)

This rule is meant to also discourage use of # for stringification and ## for concatenation. As usual for macros, there are uses that are "mostly harmless", but even these can create problems for tools, such as auto completers, static analyzers, and debuggers. Often the desire to use fancy macros is a sign of an overly complex design. Also, # and ## encourages the definition and use of macros:

本规则也不鼓励使用#和##进行字符串的转换和链接。一般来讲,很多情况下使用宏都是基本无害的,但是即使是这样也会为工具带来困难,例如有些自动补全软件,静态分析软件和调试器等。通常使用花哨的宏定义是过于复杂的设计的信号。#和##也会鼓励宏的定义和使用。

#define CAT(a, b) a ## b
#define STRINGIFY(a) #a

void f(int x, int y)
{
    string CAT(x, y) = "asdf";   // BAD: hard for tools to handle (and ugly)
    string sx2 = STRINGIFY(x);
    // ...
}

There are workarounds for low-level string manipulation using macros. For example:

确实存在需要使用宏定义进行底层字符串操作时可以使用一些变通,例如:

 

string s = "asdf" "lkjh";   // ordinary string literal concatenation

enum E { a, b };

template<int x>
constexpr const char* stringify()
{
    switch (x) {
    case a: return "a";
    case b: return "b";
    }
}

void f(int x, int y)
{
    string sx = stringify<x>();
    // ...
}

This is not as convenient as a macro to define, but as easy to use, has zero overhead, and is typed and scoped.

这段代码不像定义宏那么容易,但同样方便使用,不存在额外的开销,并且包含类型和范围。

 

In the future, static reflection is likely to eliminate the last needs for the preprocessor for program text manipulation.

将来,静态反射机制应该可以消除在程序中处理文本时使用预处理器的最后一个需求。

 

Enforcement(实施建议)

Scream when you see a macro that isn't just used for source control (e.g., #ifdef)

当给你看到宏定义不是用于代码控制(例如#ifdef)时,一定要尖叫。

 

原文链接

https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#es30-dont-use-macros-for-program-text-manipulation

 


 

觉得本文有帮助?欢迎点赞并分享给更多的人。

阅读更多更新文章,请关注微信公众号【面向对象思考】

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章