追踪设施

如果您曾经需要调试宏展开,您就会发现您的工具对这项任务的支持很少或几乎没有。因此,Wave 库提供了一个追踪设施,该设施允许选择性地获取有关某个宏或多个宏展开的信息。

宏展开的追踪会生成大量信息,因此建议您只为有问题的宏显式启用/禁用追踪。这可以通过一种特殊的Wave特定 #pragma

    #pragma wave trace(enable)    // enable the tracing
    // the macro expansions here will be traced
    // ...
    #pragma wave trace(disable)   // disable the tracing

在 C99 模式下或指定--variadics命令行选项时,您还可以使用operator _Pragma()变体来启用/禁用追踪输出。

    #define CONCAT(x, y) \
        _Pragma("wave trace(enable)") \
        x \
        _Pragma("wave trace(disable)") \
        ## y

这样,您就有可能只在宏的某一部分展开期间启用追踪。在所示示例中,追踪了宏参数'x'only. Note, that theoperator _Pragma()指令在宏展开结果中展开为空。

要查看Wavedriver 在展开简单宏时生成的内容,让我们来看一下下面示例的追踪输出:

    // test.cpp
    #define X(x)          x
#define Y() 2
#define CONCAT_(x, y) x ## y #define CONCAT(x, y) CONCAT_(x, y) #pragma wave trace(enable) // this macro expansion is to be traced CONCAT(X(1), Y()) // should expand to 12 #pragma wave trace(disable)

使用'wave -t test.trace test.cpp'theWave预处理后,driver 会生成一个文件test.trace,其中包含(不含行号):

  1: test.cpp:8:1: CONCAT(X(1), Y())
  2:   test.cpp:5:9: see macro definition: CONCAT(x, y)
  3:   invoked with
  4:   [
  5:     x = X(1)
  6:     y = Y()
  7:   ]
  8:   [
  9:     test.cpp:2:9: see macro definition: X(x)
 10:     invoked with
 11:     [
 12:       x = 1
 13:     ]
 14:     [
 15:       1
 16:       rescanning
 17:       [
 18:         1
 19:       ]
 20:     ]
 21:     test.cpp:3:9: see macro definition: Y()
 22:     [
 23:       2
 24:       rescanning
 25:       [
 26:         2
 27:       ]
 28:     ]
 29:     CONCAT_(1, 2)
 30:     rescanning
 31:     [
 32:       test.cpp:4:9: see macro definition: CONCAT_(x, y)
 33:       invoked with
 34:       [
 35:         x = 1
 36:         y = 2
 37:       ]
 38:       [
 39:         12
 40:         rescanning
 41:         [
 42:           12
 43:         ]
 44:       ]
 45:       12
 46:     ]
 47:   ]

生成的追踪输出非常详细,但允许您跟随实际宏展开过程的每一步。此追踪示例中的第一行包含宏展开启动位置的引用。此外,对于每次宏展开,还会包含以下信息:

找到的每个要展开的宏都会在追踪输出中增加一个缩进级别。