|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 got a tracing facility, which allows to get selectively some information about the expansion of a certain macro or several macros.
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:
#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:
#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.
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:
// 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):
1: test.cpp(8): CONCAT(X(1), Y()) 2: test.cpp(5): see macro definition: CONCAT(x, y) 3: invoked with 4: [ 5: x = X(1) 6: y = Y() 7: ] 8: [ 9: test.cpp(2): 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): 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): 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.
Copyright © 2003-2005 Hartmut Kaiser
Distributed under the Boost Software License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
Last updated: Thursday, December 1, 2005 21:28