C ++ FAQ的不安全宏解释? [英] Explanation of C++ FAQ's unsafe macro?

查看:209
本文介绍了C ++ FAQ的不安全宏解释?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

根据C ++ FAQ,宏是邪恶

[9.5]为什么我应该用内联函数而不是简单的#define
  宏?

[9.5] Why should I use inline functions instead of plain old #define macros?

由于的#define 宏在4个不同的罪恶:罪恶#1,罪恶#2,
  邪恶的#3,#邪4。有时候,你无论如何都应该使用他们,但他们
  还是邪恶的。
       不像的#define 宏,内联函数避免臭名昭著的宏观错误,因为内联函数总是精确地评估每个参数
  一旦。换句话说,调用内联函数在语义上只
  就像调用一个普通的功能,只是速度更快:

Because #define macros are evil in 4 different ways: evil#1, evil#2, evil#3, and evil#4. Sometimes you should use them anyway, but they're still evil. Unlike #define macros, inline functions avoid infamous macro errors since inline functions always evaluate every argument exactly once. In other words, invoking an inline function is semantically just like invoking a regular function, only faster:

// A macro that returns the absolute value of i
#define unsafe(i)  \
        ( (i) >= 0 ? (i) : -(i) )

// An inline function that returns the absolute value of i
inline
int safe(int i)
{
  return i >= 0 ? i : -i;
}

int f();

void userCode(int x)
{
  int ans;

  ans = unsafe(x++);   // Error! x is incremented twice
  ans = unsafe(f());   // Danger! f() is called twice

  ans = safe(x++);     // Correct! x is incremented once
  ans = safe(f());     // Correct! f() is called once
}


  
  

也不像宏,参数类型进行检查,并在必要
  转换正确执行。

Also unlike macros, argument types are checked, and necessary conversions are performed correctly.

宏是对健康不利;除非你有没有使用这些。

Macros are bad for your health; don't use them unless you have to.

有人能解释为什么是不安全(X ++)递增 X 两次?我无法弄清楚。

Can someone explain why is unsafe(x++) increments x twice? I am not able to figure out.

推荐答案

通过preprocessor运行它说明问题了。使用的gcc -E (也可以使用 CPP-P ,其中 -P 选项还燮presses 行),

Running it through the preprocessor shows the problem. Using gcc -E (can also use cpp -P, where the -P option also suppresses generated # lines),

inline
int safe(int i)
{
  return i >= 0 ? i : -i;
}

int f();

void userCode(int x)
{
  int ans;

  //    increment 1      increment 2 (one of these)
  //        |             |     |
  //        V             V     V
  ans = ( (x++) >= 0 ? (x++) : -(x++) );
  ans = ( (f()) >= 0 ? (f()) : -(f()) );

  ans = safe(x++);
  ans = safe(f());
}

由于烂漫噪音笔记,功能 F()也由不安全宏调用两次。也许它的纯粹的(没有副作用),所以它不是的错误的,本身。但还是不理想。

As artless noise notes, the function f() is also called twice by the unsafe macro. Perhaps it's pure (has no side-effects) so it's not wrong, per se. But still suboptimal.

所以,因为内联函数比函数宏通常更安全,因为他们在与其他基本要素相同的语义层面的工作:变量和前pressions;和清单常量,枚举 s时,可以常常更加的整理的; 什么是的的宏的使用?

So, since inline functions are generally safer than function-like macros because they work on the same semantic level with the other basic elements: variables and expressions; and for manifest constants, enums can often be more tidy; what are the good uses of macros?

设置只在编译时已知常量。您可以在编译时定义的命令行的宏。而不是

Setting constants known only at compile-time. You can define a macro from the command-line when compiling. Instead of

#define X 12

在源文件中,可以添加

in the source file, you can add

-DX=12

CC 命令。您也可以和#undef X 从与命令行-UX

to the cc command. You can also #undef X from the command-line with -UX.

这样可以允许有条件的编译,如:

This allows things like conditional-compilation, eg.

#if X
   do this;
#else
   do that;
#endif
   while (loop);

由一个makefile控制,本身或许与配置脚本生成的。

to be controlled by a makefile, itself perhaps generated with a configure script.

X-宏即可。用于X宏最引人注目的使用,国际海事组织,是有关联的字符串打印枚举标识符。虽然它让看第一好笑,这降低了这些类型的并行定义重复和同步问题。

X-Macros. The most compelling use for X-Macros, IMO, is associating enum identifiers with printable strings. While it make look funny at first, it reduces duplication and synchronization issues with these kinds of parallel definitions.

#define NAMES(_) _(Alice) _(Bob) _(Caravaggio) _(DuncanIdaho)
#define BARE(_) _ ,
#define STRG(_) #_ ,
enum { NAMES(BARE) };
char *names[] = { NAMES(STRG) };

注意,您可以通过使用参数传递宏的名称作为参数传递给另一个宏,然后调用通过宏观的,如果的它是自己的宏(因为它的之一)。欲了解更多有关的X宏,请参见这个问题

Notice that you can pass a macro's name as an argument to another macro and then call the passed macro by using the argument as if it were itself a macro (because it is one). For more on X-Macros, see this question.

这篇关于C ++ FAQ的不安全宏解释?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆