The Tracing Facility 跟蹤工具


If you ever had the need to debug a macro expansion you had to discover, that your tools provide only little or no support for this task. For this reason the Wave library has a tracing facility, which allows to get selectively some information about the expansion of a certain macro or several macros.
如果你需要對宏展開進行調試,你會發現你的工具只對此提供了很少或沒有支持。出於這個原因,Wave 庫有一個跟蹤工具,它可以有選擇地獲得一些關於某個或某幾個宏的展開的信息。

The tracing of macro expansions generates a possibly huge amount of information, so it is recommended, that you explicitely enable/disable the tracing for the macro in question only. This may be done with the help of a special, Wave specific #pragma:
對宏展開的跟蹤可能會產生非常大量的信息,所以我們建議你只對有問題的宏明確地啟用/禁用跟蹤。這可以使用一個 Wave 專用的 #pragma 來實現:

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

In C99 mode or when specifying the --variadics command line option you may additionally use the operator _Pragma() variant to enable/disable the tracing output:
在C99模式下或指定了 --variadics 命令行選項時,你可能要另外使用 operator _Pragma() 變體來啟用/禁用跟蹤信息的輸出:

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

This way you have the possibility to enable the tracing during the expansion of a part of a macro only. In the sample shown there is traced the expansion of the macro argument 'x' only. Note, that the operator _Pragma() directives expand to nothing inside the macro expansion result.
你也可以僅在一個宏的部分展開中啟用跟蹤。以上示例只跟蹤宏參數 'x' 的展開。注意,在宏展開結果中 operator _Pragma() 指令被展開為空。

To see, what the Wave driver generates while expanding a simple macro, let's have a look at the tracing output for the following example:
為了看看在展開一個簡單的宏時 Wave 驅動器會生成些什麼,我們來看一下以下例子的跟蹤輸出:

    // 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)

When preprocessed with 'wave -t test.trace test.cpp' the Wave driver generates a file test.trace, which contains (without the line numbers in front of the lines):
使用 'wave -t test.trace test.cpp' 來進行預處理,Wave 驅動器將生成一個文件 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: ]

The generated trace output is very verbose, but allows to follow every step of the actual macro expansion process. The first line in this tracing example contains the reference to the position, from where the macro expansion was initiated. Additionally the following information is contained for every single macro expansion:

Every found macro to expand will add an additional indentation level inside the trace output.