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

 


 

覺得本文有幫助?歡迎點贊並分享給更多的人。

閱讀更多更新文章,請關注微信公衆號【面向對象思考】

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