关于c/c++语言接口,实体声明与定义问题以及新的预处理器的需要的讨论
个人以为声明语句与定义语句模糊不清,例如:
extern int8 c; /* 声明, 不是定义 */
int8 c; /* 声明, 或定义 */
int8 c = 2; /* 定义, 不是声明 */
通常一个模块似乎有两个文件, 例如: mod.c, mod.h
而在 mod.c 中似乎应 #include "mod.h", 好象可以解释为: mod.c 中 需要的宏, 数据类型的定义在 mod.h 中. 那么模块内的私有(文件作用域)变量的定义应该放在哪里,而公有(全局的)变量的定义又该放在哪里?
注意,上面说的是定义, 显然, 定义似乎可以放在 mod.h, 但是更应该放在 mod.c 中, 但是, 这样一来, mod.h 中应该只包含类型和宏定义, 而变量和函数,无论全局与否, 都只应声明, 不应定义.
但是前面说过, 类似 "int8 c" 这样的声明是模糊的, 而 "extern int8 c" 是清晰的(确定是声明, 并非定义, 程序设计语言, 应该严格精确, 不同于自然语言, 但是这里的模糊实在令我疑惑).那么在 mod.h 中所有的变量应该冠以 "extern" 吗? 显然, 对于客户模块(本模块的使用者)来说, mod.h 的任何变量和函数使用 extern 来修饰是完全正确的, 因为对于他们来说, 这些符号是外部的, 而且就该被保留(不得冲突). 但是对于 mod.c 来说, 如果包含了 mod.h, 试想, 在 mod.c 中定义了一个 int8 c, 但是在 mod.h 中又来了一个 extern int8 c, 那么是否冲突呢? 试验证明"不冲突". 似乎这个"冲突"与否比较远,在 link 的时候检查. 暂且不管. 至少现在知道使在 mod.h 中全部变量和函数用 extern 修饰之后, mod.c 包含它是安全的, 那么另外一个问题: 这些 externs 对于 mod.c 有意义吗? 没有! 最多仅仅是声明, 但是 mod.c 恰恰是这些 externs 的来源, 定义本身就在 mod.c 中, 何必累赘至此? 所以, mod.h 仅仅为 mod.h 提供了宏和类型定义. 而对客户模块来说, 则这些 externs 是接口.
个人认为, 模块各部分如下:
模块内部独有:所有变量和函数的定义,以及声明(可选), 这将编译成目标(obj), 所有符号成为唯一全局符号(这个符号可能是 mangle 过的), 用于 link .
模块外部独有:所有公共变量和函数的声明(不能是定义!), 用于编译时语法检查.
共享:宏和类型定义.
相应地, 文件应该有如下部分(多个文件):
1.宏和类型定义
2.公共符号(变量和函数)描述(声明, 接口),供客户模块编译时使用
3.所有符号(变量和函数)声明,供模块自己编译时使用,可选!!
4.所有符号(变量和函数)定义,编译成目标,供 link 使用
初步地, 可以认为一个模块有如下文件:
ModMt.h: 宏和类型定义
ModPub.h: 接口描述
ModPri.h: 全部变量定义, 和全部函数声明(此声明可选)
Mod.c: 函数定义
但是每一个模块都如此复杂地处理, 太麻烦, 而且, ModPub.h 和 ModPri.h 中的符号也许重叠很大. 因为这个模块也许是这样设计的: 既然我设计这样一个函数, 我就尽量让它通用, 而不是仅仅为本模块服务, 否则太浪费了。
所以理想的代码写法和处理过程应该如此:
/* -------- File: Mod.raw -------- */
Shared
{
宏定义和类型定义
}
Vars
{
全部变量定义
引出符号需要加一个标志,例如 public 供预处理器提取时识别
}
body
{
全部函数定义
}
然后附加一个预处理器, 使它自动根据 Mod.raw 生成 ModMt.h, ModPub.h, ModPri.h, Mod.c
以上是我近日的一点想法,不知道诸位有否高见,或者别的语言有否更合适的处理方法? 谢谢!