VC 宏展开

相信很多人入门时都使用 MASM,这的 MASM 就是 Microsoft‘s Macro Assembler。其中的 Macro 就是宏的意思。相比函数,宏具有更加简洁,运行速度快(编译器会对代码进行“宏展开”,直接修改代码)等等特点。但是,如果需要调试和阅读具有多层宏定义就非常痛苦了。很多年前我接触到的P公司的BIOS代码就是这样,乍一看代码非常规整,每一行就像一个洋葱,追踪起来一层又一层,让人感叹阅读代码是个系统工程。

最近偶然看到 GCC 有展开宏功能,同样的在Microsoft 的Visual C++上也有类似功能,通过编译指令 /p 或者 /ep 即可实现。这两个参数的区别在于生成的” 预编译文件”是否有行号。例如,编写下面的代码,其中定义一个名为 SUM 的宏:

#include  <Uefi.h>
#include  <Library/UefiLib.h>
#include  <Library/ShellCEntryLib.h>
#define SUM(a,b) a+b


/***
  Print a welcoming message.

  Establishes the main structure of the application.

  @retval  0         The application exited normally.
  @retval  Other     An error occurred.
***/
INTN
EFIAPI
ShellAppMain (
  IN UINTN Argc,
  IN CHAR16 **Argv
  )
{
        int c =3,d=4;

  Print(L"Hello there fellow Programmer.\n");
  Print(L"Welcome to the world of EDK II.\n");

  Print(L"Macro test %d\n",SUM(c,d));
  
  return(0);
}

在 INF 中定义如下:

[BuildOptions]
  MSFT:*_*_X64_CC_FLAGS  = /P

在Build 目录下有生成一个 hello.i 其中有如下代码断,可以看到 SUM 宏已经展开。

INTN
__cdecl
ShellAppMain (
   UINTN Argc,
   CHAR16 **Argv
  )
{
        int c =3,d=4;

  Print(L"Hello there fellow Programmer.\n");
  Print(L"Welcome to the world of EDK II.\n");

  Print(L"Macro test %d\n",c+d);
  
  return(0);
}

如果使用 /EP  /P 参数,那么生成的预编译文件中不会有行号:

[BuildOptions]
  MSFT:*_*_X64_CC_FLAGS  = /EP /P

下图中,左侧是 /EP /P 参数的运行结果,右侧是/P 的结果:

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注