关于选择函数和宏的建议Recommendations for Choosing Between Functions and Macros

大多数 Microsoft 运行库例程都是编译的或汇编的函数,但有些例程是作为宏实现的。Most Microsoft run-time library routines are compiled or assembled functions, but some routines are implemented as macros. 当标头文件声明例程的函数和宏版本时,将优先考虑宏定义,因为它始终显示在函数声明之后。When a header file declares both a function and a macro version of a routine, the macro definition takes precedence, because it always appears after the function declaration. 在调用作为函数和宏实现的例程时,您可以通过两种方法强制编译器使用函数版本:When you invoke a routine that is implemented as both a function and a macro, you can force the compiler to use the function version in two ways:

  • 将例程名称用括号括起来。Enclose the routine name in parentheses.

    #include <ctype.h>  
    a = _toupper(a);    // Use macro version of toupper.  
    a = (_toupper)(a);  // Force compiler to use   
                        // function version of toupper.  
    
  • 使用 #undef 指令“取消定义”宏:"Undefine" the macro definition with the #undef directive:

    #include <ctype.h>  
    #undef _toupper  
    

    如果您需要在库例程的函数和宏实现之间进行选择,请考虑以下折衷方案:If you need to choose between a function and a macro implementation of a library routine, consider the following trade-offs:

  • 速度与大小 使用宏的主要好处是执行速度更快。Speed versus size The main benefit of using macros is faster execution time. 在预处理期间,宏在被使用时将内联展开(由其定义替换)。During preprocessing, a macro is expanded (replaced by its definition) inline each time it is used. 无论调用函数定义多少次,它仅执行一次。A function definition occurs only once regardless of how many times it is called. 宏可能会增加代码大小,但不会产生与函数调用关联的开销。Macros may increase code size but do not have the overhead associated with function calls.

  • 函数计算 函数的计算结果为地址;而宏不是。Function evaluation A function evaluates to an address; a macro does not. 因此,您不能在需要指针的上下文中使用宏名称。Thus you cannot use a macro name in contexts requiring a pointer. 例如,您可以声明指向函数的指针而不是指向宏的指针。For instance, you can declare a pointer to a function, but not a pointer to a macro.

  • 类型检查 在声明函数时,编译器会检查参数类型。Type-checking When you declare a function, the compiler can check the argument types. 由于你不能声明宏,因此编译器无法检查宏自变量类型;尽管它可以检查传递给宏的自变量的数目。Because you cannot declare a macro, the compiler cannot check macro argument types; although it can check the number of arguments you pass to a macro.

另请参阅See Also

CRT 库功能CRT Library Features