c - 为什么要在 .c 文件中避免使用#ifdef?

标签 c conditional-compilation

我尊敬的一位程序员说,在 C 代码中,应该不惜一切代价避免 #if#ifdef,除非可能在头文件中。为什么在 .c 文件中使用 #ifdef 会被认为是不好的编程习惯?

最佳答案

难以维护。最好使用接口(interface)来抽象特定于平台的代码,而不是通过在整个实现中散布 #ifdef 来滥用条件编译。

例如

void foo() {
#ifdef WIN32
   // do Windows stuff
#else
   // do Posix stuff
#endif
   // do general stuff
}

不好看。取而代之的是文件 foo_w32.cfoo_psx.c

foo_w32.c:

void foo() {
    // windows implementation
}

foo_psx.c:

void foo() {
    // posix implementation
}

foo.h:

void foo();  // common interface

然后有 2 个 makefile1:Makefile.winMakefile.psx,每个都编译相应的 .c 文件并链接到正确的对象。

小修改:

如果 foo() 的实现依赖于一些出现在所有平台上的代码,例如common_stuff()2,只需在您的 foo() 实现中调用它即可。

例如

通用.h:

void common_stuff();  // May be implemented in common.c, or maybe has multiple
                      // implementations in common_{A, B, ...} for platforms
                      // { A, B, ... }. Irrelevant.

foo_{w32, psx}.c:

void foo()  {  // Win32/Posix implementation
   // Stuff
   ...
   if (bar) {
     common_stuff();
   }
}

虽然您可能会重复对 common_stuff() 的函数调用,但您不能对每个平台的 foo() 定义进行参数化,除非它遵循非常特定的模式.通常,平台差异需要完全不同的实现并且不遵循此类模式。


  1. 此处使用 Makefile 进行说明。您的构建系统可能根本不使用 make,例如如果您使用 Visual Studio、CMake、Scons 等。
  2. 即使 common_stuff() 实际上有多个实现,因平台而异。

关于c - 为什么要在 .c 文件中避免使用#ifdef?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1851181/

相关文章:

c - 如何读取目标文件的重定位记录

c - 用于对用户输入的数组从最低到最高进行排序的程序。 C语言编程

python - 解析嵌套的条件语句

build-process - CoffeeScript/UglifyJS 中的条件编译

c - 从 .h 头文件中删除预编译指令

GCC 不同部分中的常量指针

c - 为什么动态调整字符串会导致崩溃?

c - wait3(waitpid别名)在不应将errno设置为ECHILD的情况下返回-1

c# - 引用程序集中的条件编译

asp.net-mvc - 我如何 "White Label"我的 ASP.Net MVC 应用程序?