#ifdef 与 #if - 作为启用/禁用特定代码部分编译的方法,哪种更好/更安全?

发布于 2024-07-06 07:42:20 字数 1723 浏览 7 评论 0原文

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(21

蹲在坟头点根烟 2024-07-13 07:42:20

我最初的反应是#ifdef,当然,但我认为#if实际上对此有一些显着的优势 - 原因如下:

首先,你可以在预处理器编译测试中使用DEBUG_ENABLED。 示例 - 通常,我希望在启用调试时有更长的超时时间,因此使用 #if,我可以这样写

  DoSomethingSlowWithTimeout(DEBUG_ENABLED? 5000 : 1000);

... 而不是 ...

#ifdef DEBUG_MODE
  DoSomethingSlowWithTimeout(5000);
#else
  DoSomethingSlowWithTimeout(1000);
#endif

其次,如果您想,您处于更好的位置从#define 迁移到全局常量。 #define 通常不被大多数 C++ 程序员所接受。

第三,你说你的团队存在分歧。 我的猜测是,这意味着不同的成员已经采用了不同的方法,您需要标准化。 判定 #if 为首选意味着使用 #ifdef 的代码即使在 DEBUG_ENABLED 为 false 时也将编译并运行。 跟踪和删除不应该生成的调试输出比反之亦然要容易得多。

哦,还有一个小的可读性问题。 您应该能够在 #define 中使用 true/false 而不是 0/1,并且由于该值是单个词法标记,因此这是您不需要在其周围添加括号的一次。

#define DEBUG_ENABLED true

代替

#define DEBUG_ENABLED (1)

My initial reaction was #ifdef, of course, but I think #if actually has some significant advantages for this - here's why:

First, you can use DEBUG_ENABLED in preprocessor and compiled tests. Example - Often, I want longer timeouts when debug is enabled, so using #if, I can write this

  DoSomethingSlowWithTimeout(DEBUG_ENABLED? 5000 : 1000);

... instead of ...

#ifdef DEBUG_MODE
  DoSomethingSlowWithTimeout(5000);
#else
  DoSomethingSlowWithTimeout(1000);
#endif

Second, you're in a better position if you want to migrate from a #define to a global constant. #defines are usually frowned on by most C++ programmers.

And, Third, you say you've a divide in your team. My guess is this means different members have already adopted different approaches, and you need to standardise. Ruling that #if is the preferred choice means that code using #ifdef will compile -and run- even when DEBUG_ENABLED is false. And it's much easier to track down and remove debug output that is produced when it shouldn't be than vice-versa.

Oh, and a minor readability point. You should be able to use true/false rather than 0/1 in your #define, and because the value is a single lexical token, it's the one time you don't need parentheses around it.

#define DEBUG_ENABLED true

instead of

#define DEBUG_ENABLED (1)
攀登最高峰 2024-07-13 07:42:20

他们俩都很丑。 相反,请执行以下操作:

#ifdef DEBUG
#define D(x) do { x } while(0)
#else
#define D(x) do { } while(0)
#endif

然后,每当您需要调试代码时,请将其放入 D(); 中。 而且您的程序不会被 #ifdef 的可怕迷宫所污染。

They're both hideous. Instead, do this:

#ifdef DEBUG
#define D(x) do { x } while(0)
#else
#define D(x) do { } while(0)
#endif

Then whenever you need debug code, put it inside D();. And your program isn't polluted with hideous mazes of #ifdef.

李白 2024-07-13 07:42:20

#ifdef 只是检查是否定义了令牌,

#define FOO 0

然后给出

#ifdef FOO // is true
#if FOO // is false, because it evaluates to "#if 0"

#ifdef just checks if a token is defined, given

#define FOO 0

then

#ifdef FOO // is true
#if FOO // is false, because it evaluates to "#if 0"
城歌 2024-07-13 07:42:20

我们在多个文件中遇到了同样的问题,并且总是存在人们忘记包含“功能标志”文件的问题(对于超过 41,000 个文件的代码库,很容易做到)。

如果您有 feature.h:

#ifndef FEATURE_H
#define FEATURE_H

// turn on cool new feature
#define COOL_FEATURE 1

#endif // FEATURE_H

但您忘记在 file.cpp 中包含头文件:

#if COOL_FEATURE
    // definitely awesome stuff here...
#endif

那么您就会遇到问题,在这种情况下,编译器将未定义的 COOL_FEATURE 解释为“false”,并且无法包含代码。 是的,gcc 确实支持一个会导致未定义宏错误的标志...但是大多数第 3 方代码要么定义要么不定义功能,因此这不是那么可移植。

我们采用了一种可移植的方法来纠正这种情况并测试功能的状态:函数宏。

如果您将上述 feature.h 更改为:

#ifndef FEATURE_H
#define FEATURE_H

// turn on cool new feature
#define COOL_FEATURE() 1

#endif // FEATURE_H

但是您再次忘记在 file.cpp 中包含头文件:

#if COOL_FEATURE()
    // definitely awseome stuff here...
#endif

由于使用了未定义的函数宏,预处理器会出错。

We have had this same problem across multiple files and there is always the problem with people forgetting to include a "features flag" file (With a codebase of > 41,000 files it is easy to do).

If you had feature.h:

#ifndef FEATURE_H
#define FEATURE_H

// turn on cool new feature
#define COOL_FEATURE 1

#endif // FEATURE_H

But then You forgot to include the header file in file.cpp:

#if COOL_FEATURE
    // definitely awesome stuff here...
#endif

Then you have a problem, the compiler interprets COOL_FEATURE being undefined as a "false" in this case and fails to include the code. Yes gcc does support a flag that causes a error for undefined macros... but most 3rd party code either defines or does not define features so this would not be that portable.

We have adopted a portable way of correcting for this case as well as testing for a feature's state: function macros.

if you changed the above feature.h to:

#ifndef FEATURE_H
#define FEATURE_H

// turn on cool new feature
#define COOL_FEATURE() 1

#endif // FEATURE_H

But then you again forgot to include the header file in file.cpp:

#if COOL_FEATURE()
    // definitely awseome stuff here...
#endif

The preprocessor would have errored out because of the use of an undefined function macro.

趴在窗边数星星i 2024-07-13 07:42:20

出于执行条件编译的目的,#if 和 #ifdef 几乎相同,但不完全相同。 如果您的条件编译依赖于两个符号,那么 #ifdef 将不起作用。 例如,假设您有两个条件编译符号:PRO_VERSION 和 TRIAL_VERSION,您可能会遇到类似这样的情况:

#if defined(PRO_VERSION) && !defined(TRIAL_VERSION)
...
#else
...
#endif

使用 #ifdef 会使上述情况变得更加复杂,尤其是让 #else 部分正常工作。

我的代码广泛使用条件编译,我们混合使用了 #if 和 #if 。 #ifdef。 对于简单的情况,我们倾向于使用#ifdef/#ifndef,而每当评估两个或多个符号时,我们倾向于使用#if。

For the purposes of performing conditional compilation, #if and #ifdef are almost the same, but not quite. If your conditional compilation depends on two symbols then #ifdef will not work as well. For example, suppose you have two conditional compilation symbols, PRO_VERSION and TRIAL_VERSION, you might have something like this:

#if defined(PRO_VERSION) && !defined(TRIAL_VERSION)
...
#else
...
#endif

Using #ifdef the above becomes much more complicated, especially getting the #else part to work.

I work on code that uses conditional compilation extensively and we have a mixture of #if & #ifdef. We tend to use #ifdef/#ifndef for the simple case and #if whenever two or more symbols are being evaluation.

单调的奢华 2024-07-13 07:42:20

我认为这完全是风格问题。 两者实际上都没有比对方明显的优势。

一致性比任何特定选择都更重要,因此我建议您与团队一起选择一种风格并坚持下去。

I think it's entirely a question of style. Neither really has an obvious advantage over the other.

Consistency is more important than either particular choice, so I'd recommend that you get together with your team and pick one style, and stick to it.

浪漫之都 2024-07-13 07:42:20

我自己更喜欢:

#if defined(DEBUG_ENABLED)

因为它可以更轻松地创建寻找相反条件的代码,并且更容易发现:

#if !defined(DEBUG_ENABLED)

#ifndef(DEBUG_ENABLED)

I myself prefer:

#if defined(DEBUG_ENABLED)

Since it makes it easier to create code that looks for the opposite condition much easier to spot:

#if !defined(DEBUG_ENABLED)

vs.

#ifndef(DEBUG_ENABLED)
﹏半生如梦愿梦如真 2024-07-13 07:42:20

这是风格问题。 但我推荐一种更简洁的方法:

#ifdef USE_DEBUG
#define debug_print printf
#else
#define debug_print
#endif

debug_print("i=%d\n", i);

执行一次,然后始终使用 debug_print() 进行打印或不执行任何操作。 (是的,这两种情况都会编译。)这样,您的代码就不会因预处理器指令而出现乱码。

如果您收到警告“表达式无效”并且想要摆脱它,可以使用以下替代方法:

void dummy(const char*, ...)
{}

#ifdef USE_DEBUG
#define debug_print printf
#else
#define debug_print dummy
#endif

debug_print("i=%d\n", i);

It's a matter of style. But I recommend a more concise way of doing this:

#ifdef USE_DEBUG
#define debug_print printf
#else
#define debug_print
#endif

debug_print("i=%d\n", i);

You do this once, then always use debug_print() to either print or do nothing. (Yes, this will compile in both cases.) This way, your code won't be garbled with preprocessor directives.

If you get the warning "expression has no effect" and want to get rid of it, here's an alternative:

void dummy(const char*, ...)
{}

#ifdef USE_DEBUG
#define debug_print printf
#else
#define debug_print dummy
#endif

debug_print("i=%d\n", i);
流年已逝 2024-07-13 07:42:20

#if 使您可以选择将其设置为 0 以关闭该功能,同时仍然检测开关是否存在。
就我个人而言,我总是#define DEBUG 1,这样我就可以用 #if 或 #ifdef 捕获它

#if gives you the option of setting it to 0 to turn off the functionality, while still detecting that the switch is there.
Personally I always #define DEBUG 1 so I can catch it with either an #if or #ifdef

佼人 2024-07-13 07:42:20

#if 和#define MY_MACRO (0)

使用#if 意味着您创建了一个“define”宏,即将在代码中搜索的内容替换为“(0)”。 这是我讨厌在 C++ 中看到的“宏地狱”,因为它会通过潜在的代码修改来污染代码。

例如:

#define MY_MACRO (0)

int doSomething(int p_iValue)
{
   return p_iValue + 1 ;
}

int main(int argc, char **argv)
{
   int MY_MACRO = 25 ;
   doSomething(MY_MACRO) ;

   return 0;
}

在 g++ 上给出以下错误:

main.cpp|408|error: lvalue required as left operand of assignment|
||=== Build finished: 1 errors, 0 warnings ===|

只有一个错误。

这意味着您的宏已成功与 C++ 代码交互:函数调用成功。 在这个简单的例子中,它很有趣。 但我自己在代码中默默地使用宏的经验并不充满乐趣和满足,所以...

#ifdef 和 #define MY_MACRO

使用 #ifdef 意味着您“定义”某些东西。 并不是说你赋予它一个值。 它仍然是污染性的,但至少,它将被“替换为空”,并且不会被 C++ 代码视为合法的代码语句。 上面相同的代码,有一个简单的定义,它:

#define MY_MACRO

int doSomething(int p_iValue)
{
   return p_iValue + 1 ;
}

int main(int argc, char **argv)
{
   int MY_MACRO = 25 ;
   doSomething(MY_MACRO) ;

   return 0;
}

给出以下警告:

main.cpp||In function ‘int main(int, char**)’:|
main.cpp|406|error: expected unqualified-id before ‘=’ token|
main.cpp|399|error: too few arguments to function ‘int doSomething(int)’|
main.cpp|407|error: at this point in file|
||=== Build finished: 3 errors, 0 warnings ===|

所以...

结论

我宁愿在代码中没有宏,但出于多种原因(定义标头保护或调试宏),我可以' t。

但至少,我喜欢让它们与我的合法 C++ 代码交互最少。 这意味着使用没有值的#define,使用#ifdef和#ifndef(甚至是吉姆·巴克建议的#if定义),最重要的是,给它们起这么长、这么陌生的名字,任何一个头脑清醒的人都不会使用它是“偶然”的,并且绝不会影响合法的 C++ 代码。

现在,当我重新阅读我的文章时

,我想知道我是否不应该尝试找到一些永远不会是正确的 C++ 的值来添加到我的定义中。 类似的东西

#define MY_MACRO @@@@@@@@@@@@@@@@@@

可以与 #ifdef 和 #ifndef 一起使用,但如果在函数内部使用,则不允许代码编译...我在 g++ 上成功尝试了这一点,它给出了错误:

main.cpp|410|error: stray ‘@’ in program|

有趣。
:-)

#if and #define MY_MACRO (0)

Using #if means that you created a "define" macro, i.e., something that will be searched in the code to be replaced by "(0)". This is the "macro hell" I hate to see in C++, because it pollutes the code with potential code modifications.

For example:

#define MY_MACRO (0)

int doSomething(int p_iValue)
{
   return p_iValue + 1 ;
}

int main(int argc, char **argv)
{
   int MY_MACRO = 25 ;
   doSomething(MY_MACRO) ;

   return 0;
}

gives the following error on g++:

main.cpp|408|error: lvalue required as left operand of assignment|
||=== Build finished: 1 errors, 0 warnings ===|

Only one error.

Which means that your macro successfully interacted with your C++ code: The call to the function was successful. In this simple case, it is amusing. But my own experience with macros playing silently with my code is not full of joy and fullfilment, so...

#ifdef and #define MY_MACRO

Using #ifdef means you "define" something. Not that you give it a value. It is still polluting, but at least, it will be "replaced by nothing", and not seen by C++ code as lagitimate code statement. The same code above, with a simple define, it:

#define MY_MACRO

int doSomething(int p_iValue)
{
   return p_iValue + 1 ;
}

int main(int argc, char **argv)
{
   int MY_MACRO = 25 ;
   doSomething(MY_MACRO) ;

   return 0;
}

Gives the following warnings:

main.cpp||In function ‘int main(int, char**)’:|
main.cpp|406|error: expected unqualified-id before ‘=’ token|
main.cpp|399|error: too few arguments to function ‘int doSomething(int)’|
main.cpp|407|error: at this point in file|
||=== Build finished: 3 errors, 0 warnings ===|

So...

Conclusion

I'd rather live without macros in my code, but for multiple reasons (defining header guards, or debug macros), I can't.

But at least, I like to make them the least interactive possible with my legitimate C++ code. Which means using #define without value, using #ifdef and #ifndef (or even #if defined as suggested by Jim Buck), and most of all, giving them names so long and so alien no one in his/her right mind will use it "by chance", and that in no way it will affect legitimate C++ code.

Post Scriptum

Now, as I'm re-reading my post, I wonder if I should not try to find some value that won't ever ever be correct C++ to add to my define. Something like

#define MY_MACRO @@@@@@@@@@@@@@@@@@

that could be used with #ifdef and #ifndef, but not let code compile if used inside a function... I tried this successfully on g++, and it gave the error:

main.cpp|410|error: stray ‘@’ in program|

Interesting.
:-)

木緿 2024-07-13 07:42:20

这根本不是风格问题。 不幸的是,这个问题也是错误的。 您无法从更好或更安全的意义上比较这些预处理器指令。

#ifdef macro

意思是“如果定义了宏”或“如果宏存在”。 宏的值在这里并不重要。 它可以是任何东西。

#if macro

if 总是与一个值进行比较。 在上面的示例中,它是标准隐式比较:

#if macro !=0

#if 用法的示例,

#if CFLAG_EDITION == 0
    return EDITION_FREE;
#elif CFLAG_EDITION == 1
    return EDITION_BASIC;
#else
    return EDITION_PRO;
#endif

您现在可以将 CFLAG_EDITION 的定义放入代码中

#define CFLAG_EDITION 1 

,也可以将宏设置为编译器标志。 另请参见此处

That is not a matter of style at all. Also the question is unfortunately wrong. You cannot compare these preprocessor directives in the sense of better or safer.

#ifdef macro

means "if macro is defined" or "if macro exists". The value of macro does not matter here. It can be whatever.

#if macro

if always compare to a value. In the above example it is the standard implicit comparison:

#if macro !=0

example for the usage of #if

#if CFLAG_EDITION == 0
    return EDITION_FREE;
#elif CFLAG_EDITION == 1
    return EDITION_BASIC;
#else
    return EDITION_PRO;
#endif

you now can either put the definition of CFLAG_EDITION either in your code

#define CFLAG_EDITION 1 

or you can set the macro as compiler flag. Also see here.

夜血缘 2024-07-13 07:42:20

第一个对我来说似乎更清楚。 与已定义/未定义相比,将其设置为标志似乎更自然。

The first seems clearer to me. It seems more natural make it a flag as compared to defined/not defined.

谈情不如逗狗 2024-07-13 07:42:20

两者完全相同。 在惯用用法中,#ifdef 仅用于检查定义性(以及我在示例中使用的内容),而 #if 用于更复杂的表达式,例如 #if Defined(A) && !定义(B)。

Both are exactly equivalent. In idiomatic use, #ifdef is used just to check for definedness (and what I'd use in your example), whereas #if is used in more complex expressions, such as #if defined(A) && !defined(B).

韵柒 2024-07-13 07:42:20

向驱动程序指定条件定义的不同方式存在差异:

diff <( echo | g++ -DA= -dM -E - ) <( echo | g++ -DA -dM -E - )

输出:

344c344
< #define A 
---
> #define A 1

这意味着 -DA-DA=1 和 if value 的同义词被省略,那么在#if A使用的情况下可能会导致问题。

There is a difference in case of different way to specify a conditional define to the driver:

diff <( echo | g++ -DA= -dM -E - ) <( echo | g++ -DA -dM -E - )

output:

344c344
< #define A 
---
> #define A 1

This means, that -DA is synonym for -DA=1 and if value is omitted, then it may lead to problems in case of #if A usage.

以为你会在 2024-07-13 07:42:20

我曾经使用#ifdef,但是当我切换到 Doxygen 进行文档记录时,我发现注释掉的宏无法被记录(或者至少 Doxygen 会产生警告)。 这意味着我无法记录当前未启用的功能开关宏。

尽管可以仅为 Doxygen 定义宏,但这意味着代码非活动部分中的宏也将被记录。 我个人想显示功能开关,否则仅记录当前选择的内容。 此外,如果有许多宏只有在 Doxygen 处理文件时才需要定义,这会使代码变得非常混乱。

因此,在这种情况下,最好始终定义宏并使用#if

I used to use #ifdef, but when I switched to Doxygen for documentation, I found that commented-out macros cannot be documented (or, at least, Doxygen produces a warning). This means I cannot document the feature-switch macros that are not currently enabled.

Although it is possible to define the macros only for Doxygen, this means that the macros in the non-active portions of the code will be documented, too. I personally want to show the feature switches and otherwise only document what is currently selected. Furthermore, it makes the code quite messy if there are many macros that have to be defined only when Doxygen processes the file.

Therefore, in this case, it is better to always define the macros and use #if.

許願樹丅啲祈禱 2024-07-13 07:42:20

我一直使用 #ifdef 和编译器标志来定义它......

I've always used #ifdef and compiler flags to define it...

泅人 2024-07-13 07:42:20

或者,您可以声明一个全局常量,并使用 C++ if,而不是预处理器 #if。 编译器应该为您优化未使用的分支,这样您的代码就会更加干净。

这是C++ 陷阱 作者:Stephen C. Dewhurst说的是使用#if。

Alternatively, you can declare a global constant, and use the C++ if, instead of the preprocessor #if. The compiler should optimize the unused branches away for you, and your code will be cleaner.

Here is what C++ Gotchas by Stephen C. Dewhurst says about using #if's.

三生一梦 2024-07-13 07:42:20

与许多事情一样,答案取决于情况。 #ifdef 对于保证在特定单元中定义或未定义的事物非常有用。 例如,包括警卫。 如果包含文件至少出现一次,则保证定义该符号,否则不定义。

然而,有些事情并没有这样的保证。 考虑一下符号HAS_FEATURE_X。 存在多少个州?

  1. 未定义
  2. 已定义
  3. 用值(例如 0 或 1)定义。

因此,如果您正在编写代码,尤其是共享代码,其中有些代码可能 #define HAS_FEATURE_X 0 表示功能 X 不存在,而其他代码可能只是没有定义它,那么您需要处理所有这些情况。

#if !define(HAS_FEATURE_X) || HAS_FEATURE_X == 1

仅使用 #ifdef 可能会出现微妙的错误,即某些内容意外切换入(或切换出),因为某人或某个团队有将未使用的事物定义为 0 的约定在某些方面,我喜欢这种#if方法,因为它意味着程序员主动做出了决定。 留下未定义的东西是被动的,从外部的角度来看,有时可能不清楚这是故意的还是疏忽的。

As with many things, the answer depends. #ifdef is great for things that are guaranteed to be defined or not defined in a particular unit. Include guards for example. If the include file is present at least once, the symbol is guaranteed to be defined, otherwise not.

However, some things don't have that guarantee. Think about the symbol HAS_FEATURE_X. How many states exist?

  1. Undefined
  2. Defined
  3. Defined with a value (say 0 or 1).

So, if you're writing code, especially shared code, where some may #define HAS_FEATURE_X 0 to mean feature X isn't present and others may just not define it, you need to handle all those cases.

#if !defined(HAS_FEATURE_X) || HAS_FEATURE_X == 1

Using just an #ifdef could allow for a subtle error where something is switched in (or out) unexpectedly because someone or some team has a convention of defining unused things to 0. In some ways, I like this #if approach because it means the programmer actively made a decision. Leaving something undefined is passive and from an external point of view, it can sometimes be unclear whether that was intentional or an oversight.

瞎闹 2024-07-13 07:42:20

它们都有不同的用途,

  1. #if X 仅在满足以下条件时才会通过:定义了 X 并且 X 有一个值且该值不为零
  2. < code>#ifdef X 仅当定义了 X 时才会通过

They both serve different purpose,

  1. #if X will pass only if: X is defined and X has a value and the value is non zero
  2. #ifdef X will pass only if: X is defined
这个俗人 2024-07-13 07:42:20

当您可能需要多个级别的调试时,我喜欢#define DEBUG_ENABLED (0)。 例如:

#define DEBUG_RELEASE (0)
#define DEBUG_ERROR (1)
#define DEBUG_WARN (2)
#define DEBUG_MEM (3)
#ifndef DEBUG_LEVEL
#define DEBUG_LEVEL (DEBUG_RELEASE)
#endif
//...

//now not only
#if (DEBUG_LEVEL)
//...
#endif

//but also
#if (DEBUG_LEVEL >= DEBUG_MEM)
LOG("malloc'd %d bytes at %s:%d\n", size, __FILE__, __LINE__);
#endif

它使调试内存泄漏变得更容易,而无需让所有这些日志行妨碍您调试其他事情。

另外,定义周围的 #ifndef 使得在命令行中选择特定的调试级别变得更容易:

make -DDEBUG_LEVEL=2
cmake -DDEBUG_LEVEL=2

等等。

如果不是这样,我会优先考虑 #ifdef,因为编译器/make 标志将被文件中的标志覆盖。 因此,您不必担心在提交之前更改回标头。

I like #define DEBUG_ENABLED (0) when you might want multiple levels of debug. For example:

#define DEBUG_RELEASE (0)
#define DEBUG_ERROR (1)
#define DEBUG_WARN (2)
#define DEBUG_MEM (3)
#ifndef DEBUG_LEVEL
#define DEBUG_LEVEL (DEBUG_RELEASE)
#endif
//...

//now not only
#if (DEBUG_LEVEL)
//...
#endif

//but also
#if (DEBUG_LEVEL >= DEBUG_MEM)
LOG("malloc'd %d bytes at %s:%d\n", size, __FILE__, __LINE__);
#endif

It makes it easier to debug memory leaks, without having all those log lines in your way of debugging other things.

Also the #ifndef around the define makes it easier to pick a specific debug level at the commandline:

make -DDEBUG_LEVEL=2
cmake -DDEBUG_LEVEL=2

etc.

If not for this, I would give advantage to #ifdef, because the compiler/make flag would be overridden by the one in the file. So you don't have to worry about changing back the header before doing the commit.

り繁华旳梦境 2024-07-13 07:42:20

有点题外话,但在 C++ 中使用预处理器打开/关闭日志记录绝对不是最佳选择。

有一些不错的日志记录工具,例如 Apache 的 log4cxx ,它们是开源的并且不受限制您如何分发您的应用程序。 它们还允许您更改日志记录级别而无需重新编译,如果您关闭日志记录,则开销非常低,并且使您有机会在生产中完全关闭日志记录。

A little off-topic, but turning on/off logging with the preprocessor is definitely sub-optimal in C++.

There are nice logging tools like Apache's log4cxx which are open-source and don't restrict how you distribute your application. They also allow you to change logging levels without recompilation, have very low overhead if you turn logging off, and give you the chance to turn logging off completely in production.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文