摘要: 16 预处理指令1、预处理指令由预处理标记序列组成。序列的首标记为#预处理标记,它或者为源文件中的第一个字符(可位于不包含换行符的空白之后),或者位于至少包含一个换行符的空白之后。序列的最后一个标记是位于序列首标记之后的第一个换行符(因此,预处理指令通常被称为“行”。这些“行”没有其他的句法意义,在预处理中,除了某些情况之外(例如,参见16.3.2的字符串文字创建操作符#),所有的空白都是等价的)。preprocessing-file:groupoptgroup:group-partgroup group-partgroup-part:pp-tokensopt new-lineif-secti 阅读全文
posted @ 2007-03-13 21:59 Goncely 阅读(508) 评论(0) 推荐(0) 编辑
摘要: 1 调用接口cp_lexer_get_preprocessor_token: // in cp/ parser.c,C++分析器 => c_lex_with_flags => 标记C++关键字c_lex_with_flags: // in c-lex.c,C语言词法分析 => cpp_get_token // in cpplib => 过滤掉CPP_PADDING类型的标记 => 对各类型做进一步精化处理,构造tree结构2 内存接口 C和C++共用一个cpp_reader *parse_in接口(在c-common.c中定义,cp/decl2.c中有对其的外部声 阅读全文
posted @ 2006-11-14 22:50 Goncely 阅读(253) 评论(0) 推荐(0) 编辑
摘要: 在gcc中,几乎所有的东西都是用树结构串起来的,从而形成抽象语法树。tree可以看作是指向树节点的指针,所有的树节点都有一个共同的基类:tree_common。在文件coretypes.h中,tree的定义如下:#ifndef USED_FOR_TARGET...typedef union tree_node *tree; ...#else...#define tree union _dont_use_tree_here_ *...#endif可见,当USED_FOR_TARGET宏未被定义的时候,tree是指向联合类型tree_node的指针类型;否则,tree是一个定义为union _do 阅读全文
posted @ 2006-11-14 22:46 Goncely 阅读(395) 评论(0) 推荐(0) 编辑
摘要: 1、在本国际标准中,程序文本被保存在称为源文件的单元内。一个源文件,加上通过预处理指令#include包含的头文件(17.4.1.2)和其他源文件(16.2),并除去被条件包含(16.1)预处理指令限定的代码行,称为翻译单元。[注:不需要对所有的C++程序单元同时进行翻译。]2、[注:翻译单元和实例单元的翻译结果可保存在一个独立的文件或是库文件中。程序中独立的翻译单元之间可通过(例如)调用标识符具有外部链接属性的函数、操作标识符具有外部链接属性的数据或操作数据文件进行通信。可对翻译单元逐个进行翻译,之后再将它们链接以生成可执行程序(3.5)。]2.1 翻译步骤1、下列步骤说明了翻译的先后次序。 阅读全文
posted @ 2006-11-08 07:34 Goncely 阅读(407) 评论(0) 推荐(0) 编辑
摘要: 8.3 声明符的含义1、声明符列表出现在可选的(第7章)decl-specifier-seq(7.1)之后。每个声明符只能包含一个declarator-id;它对被声明的标识符进行命名。除了特殊函数(12.3, 12.4, 13.5)声明、模板特化或局部特化(14.7)声明之外,declarator-id中的unqualified-id必须是简单标识符。此外,declarator-id只在以下情况才允许使用限定形式:在所属类之外定义成员函数(9.3)或静态数据成员(9.4);在所属名字空间之外定义或显式实例化函数或变量成员;在所属名字空间之外定义已声明的显式特化;声明其它类或名字空间的成员为友 阅读全文
posted @ 2006-04-21 17:11 Goncely 阅读(479) 评论(0) 推荐(0) 编辑
摘要: 8.2 歧义消解1、由函数式转型和6.8所述声明(声明符以左括号开头)的相似性而引起的歧义也会出现在声明的上下文中。这时,构造体可能为参数名被冗余的圆括号括起来的函数声明(如int f(int (n))),也可能是具有函数式转型初始化体的对象声明(如int n(int(1.0)))。同6.8一样,歧义消解的方案是将任何能当作声明的构造体看作是一个声明(比如:优先将int (n)看作是对int型变量n的声明,而不是对变量n的强制整型转换;这样导致的一个直接后果是将int f(int (n))解析为函数声明,而不是被n初始化的整型变量f的声明。)。[注:也可通过下列方法对一个可能会引起上述歧义的声 阅读全文
posted @ 2006-04-21 12:26 Goncely 阅读(225) 评论(0) 推荐(0) 编辑
摘要: 8.1 类型名1、进行显式类型转换,或作为sizeof,,new和typeid的参量时,需要指定类型的名字。类型名字可通过type-id给出,type-id在句法上等同于省略了名字的对象或函数声明。type-id:type-specifier-seq abstract-declaratoropttype-specifier-seq:type-specifier type-specifier-seqoptabstract-declarator:ptr-operator abstract-declaratoroptdirect-abstract-declaratordirect-abstract- 阅读全文
posted @ 2006-04-21 11:22 Goncely 阅读(166) 评论(0) 推荐(0) 编辑
摘要: 8 声明符1、声明中的声明符声明了一个对象、函数或类型。出现在声明中的init-declarator-list是一个由逗号分隔的声明符序列,其中的每个声明符可具有一个初始化体。init-declarator-list:init-declaratorinit-declarator-list , init-declaratorinit-declarator:declarator initializeropt2、声明由说明符(decl-specifier-seq; 7.1)和声明符(init-declarator-list)两个部分构成。说明符给出了被声明对象、函数或类型定义的类型、存储类和其它属性 阅读全文
posted @ 2006-04-21 11:20 Goncely 阅读(392) 评论(0) 推荐(0) 编辑
摘要: 6.8 歧义消解1、在包含表达式语句和声明的语法中存有歧义:以函数式显示类型转换(5.2.3)为最左子表达式的表达式语句可能无法同第一个声明符以左括号开头的声明区分开来。在这种情况下,语句是一个声明(即当一个语句即能为表达式语句又能为声明语句的时候,优先把它当成是声明语句)。 [注:为了消歧,可能需要检查整个语句以确定其为一个表达式语句还是声明。许多例子都可用此法消除歧义。例如:假定T为simple-type-specifier(7.1.5),T(a)->m = 7; // expression-statementT(a)++; //expression-statementT(a,5)& 阅读全文
posted @ 2006-04-21 11:03 Goncely 阅读(353) 评论(0) 推荐(0) 编辑
摘要: 7.3.2 名字空间别名1、名字空间别名定义根据下述语法为名字空间声明了一个可替代的名字:namespace-alias:identifiernamespace-alias-definition:namespace identifier = qualified-namespace-specifier ;qualified-namespace-specifier:::opt nested-name-specifieropt namespace-name2、namespace-alias-definition中的标识符为qualified-namespace-specifier所指名字空间的名字的 阅读全文
posted @ 2006-04-19 15:53 Goncely 阅读(140) 评论(0) 推荐(0) 编辑