如果使用得当,这可能是一种有用的技术。
假设您有一个复杂的,性能关键的子系统,它具有相当小的公共接口和许多不可重用的实现代码。代码运行到几千行,一百个左右的私有函数和相当多的私有数据。如果您使用非平凡的嵌入式系统,您可能经常处理这种情况。
您的解决方案可能是分层的,模块化的和解耦的,通过在不同的文件中编码子系统的不同部分,可以有效地表示和加强这些方面。
使用C,你可以通过这样做而失去很多。几乎所有工具链都为单个编译单元提供了不错的优化,但对于任何声明为extern的东西都非常悲观。
如果你把所有东西放到一个C源模块中,你得到 -性能和代码大小的改进 - 在许多情况下将内联函数调用。即使没有内联,编译器也有机会生成更高效的代码。
链接级别数据和功能隐藏。
避免命名空间污染及其必然结果 - 您可以使用较少的笨拙名称。
更快的编译和链接。
但是在编辑这个文件时你也会得到一个不圣洁的混乱而你失去了隐含的模块性。这可以通过将源拆分为多个文件来解决,并将这些文件包括在内以生成单个编译单元。
您需要强制执行一些约定来正确管理它。这些在某种程度上取决于你的工具链,但一些一般指示是 -将公共接口放在单独的头文件中 - 无论如何你应该这样做。
有一个主.c文件,包含所有子.c文件。这还可以包括公共接口的代码。
使用编译器保护来确保外部编译单元不包含专用头和源模块。
应将所有私有数据和函数声明为静态。
保持.c和.h文件之间的概念区别。这利用了现有的惯例。不同之处在于您的标头中会有很多静态声明。
如果您的工具链没有强加任何理由,请将私有实现文件命名为.c和.h。如果使用包含保护,这些将不会生成代码并且不会引入新名称(在链接期间最终可能会出现一些空段)。巨大的优势是其他工具(例如IDE)将适当地处理这些文件。