关于c/c++语言接口,实体声明与定义问题以及新的预处理器的需要的讨论

jawibn 2005-11-17 01:26:32
个人以为声明语句与定义语句模糊不清,例如:
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

以上是我近日的一点想法,不知道诸位有否高见,或者别的语言有否更合适的处理方法? 谢谢!

...全文
89 3 打赏 收藏 转发到动态 举报
写回复
用AI写文章
3 条回复
切换为时间正序
请发表友善的回复…
发表回复
jawibn 2005-11-17
  • 打赏
  • 举报
回复
上面的理解可能稍有偏差,因为上面的 extern 是针对 c 函数的, 对于 c++ 函数是否如此未实验, 不能妄言.
jawibn 2005-11-17
  • 打赏
  • 举报
回复
另外,似乎 c++ 需要外部函数修饰为 extern, 而 c 不需要, 因为:
#ifdef __cplusplus
extern "C" {
#end if

我说的这样的预处理器本身很简单, 但是如果编译器能直接支持, 不是更好么?
jawibn 2005-11-17
  • 打赏
  • 举报
回复
当如上预处理之后,就很清晰了:

在 Mod.c 中 #include "ModMt.h" 和 #include "ModPri.h", 而在客户模块里 #include "ModPub.h".

69,364

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧