用C/C++做开发时,有很多的宏命令,绕来绕去的,很难看清楚关系。一般的编译器都提供了展开的命令,VC下的命令如下:
CL /EP /C YourCodeFile.cpp
This command will carry out all preprocessor directives and expand macros in the C++ code file "YourCodeFile.cpp". The/EP option suppresses compilation. /EP also suppresses the output files from the /FA, /Fa, and /Fm options. The/C (Preserve Comments During Preprocessing) option is used to preserve comments in the preprocessed output.
这个是从msdn上摘下来的,除了可以用于cpp文件之外,还可以用于.h头文件。
我将v8的ast.h展开后可以看见他的astNode类的定义:
class AstNode: public ZoneObject { public: #define DECLARE_TYPE_ENUM(type) k##type, enum Type { AST_NODE_LIST(DECLARE_TYPE_ENUM) kInvalid = -1 }; #undef DECLARE_TYPE_ENUM ..... virtual void Accept(AstVisitor* v) = 0; virtual Type node_type() const = 0; // Type testing & conversion functions overridden by concrete subclasses. #define DECLARE_NODE_FUNCTIONS(type) \ bool Is##type() { return node_type() == AstNode::k##type; } \ type* As##type() { return Is##type() ? reinterpret_cast<type*>(this) : NULL; } AST_NODE_LIST(DECLARE_NODE_FUNCTIONS) #undef DECLARE_NODE_FUNCTIONS ... }将无关的代码略掉了。展开后的结果如下:
class AstNode: public ZoneObject { public: enum Type { kVariableDeclaration, kFunctionDeclaration, kModuleDeclaration, kImportDeclaration, kExportDeclaration, kModuleLiteral, kModuleVariable, kModulePath, kModuleUrl, kBlock, kExpressionStatement, kEmptyStatement, kIfStatement, kContinueStatement, kBreakStatement, kReturnStatement, kWithStatement, kSwitchStatement, kDoWhileStatement, kWhileStatement, kForStatement, kForInStatement, kTryCatchStatement, kTryFinallyStatement, kDebuggerStatement, kFunctionLiteral, kSharedFunctionInfoLiteral, kConditional, kVariableProxy, kLiteral, kRegExpLiteral, kObjectLiteral, kArrayLiteral, kAssignment, kThrow, kProperty, kCall, kCallNew, kCallRuntime, kUnaryOperation, kCountOperation, kBinaryOperation, kCompareOperation, kThisFunction, kInvalid = -1 }; virtual void Accept(AstVisitor* v) = 0; virtual Type node_type() const = 0; // Type testing & conversion functions overridden by concrete subclasses. bool IsVariableDeclaration() { return node_type() == AstNode::kVariableDeclaration; } VariableDeclaration* AsVariableDeclaration() { return IsVariableDeclaration() ? reinterpret_cast<VariableDeclaration*>(this) : NULL; } bool IsFunctionDeclaration() { return node_type() == AstNode::kFunctionDeclaration; } FunctionDeclaration* AsFunctionDeclaration() { return IsFunctionDeclaration() ? reinterpret_cast<FunctionDeclaration*>(this) : NULL; } bool IsModuleDeclaration() { return node_type() == AstNode::kModuleDeclaration; } ModuleDeclaration* AsModuleDeclaration() { return IsModuleDeclaration() ? reinterpret_cast<ModuleDeclaration*>(this) : NULL; } .......一目了然,很好看懂了类的结构了吧...