为什么我们需要功能测试宏?

通过阅读-D_XOPEN_SOURCE 做什么/意味着什么?,我了解如何使用功能测试宏。

但是我还是不明白为什么我们需要它,我的意思是,我们可以启用所有可用的功能吗?然后文档是这样写的:这个功能只在Mac/BSD下可用,那个功能只在Linux下可用,如果你使用它,那么你的程序只能在那个系统上运行。

那么为什么我们首先需要一个功能测试宏呢?

回答

为什么我们需要它,我的意思是,我们可以启用所有可用功能吗?

想象一下,某家公司编写了完美的超级可移植代码,大致如下所示:

#include <stdlib.h>
struct someone_s { char name[20]; };

/// @brief grants Plant To someone
int grantpt(int plant_no, struct someone_s someone) {
   // some super plant granting algorithm here
   return 0;
}

int main() {
   // some program here
   struct someone_s kamil = { "Kamil" };
   return grantpt(20, kamil);
}

该程序完全正常并且一切正常,并且该程序与 C 非常兼容,因此应该可以移植到任何地方。现在想象一下_XOPEN_SOURCE不存在的时刻!客户收到该程序的源代码,并尝试在他的尖端 Unix 计算机上编译并运行它,并在经过认证的 POSIX 系统上使用经过认证的 C 编译器,然后他收到了该公司必须修复的错误,并且必须支付以下费用:

/tmp/1.c:7:9: error: conflicting types for ‘grantpt’; have ‘int(struct someone_s,  int)’
    7 |     int grantpt(struct someone_s someone, int plant_no) {
      |         ^~~~~~~
In file included from /tmp/1.c:2:
/usr/include/stdlib.h:977:12: note: previous declaration of ‘grantpt’ with type ‘int(int)’
  977 | extern int grantpt (int __fd) __THROW;
      |            ^~~~~~~

看起来 POSIX 中已经采用了为函数选择的完全随机名称 - grantpt()。

当引入不在保留空间中的新符号时,像 POSIX 这样的标准不能只是“添加它们”并期望世界不要抗议 - 冲突的定义可以并且将会并且确实会破坏有效的程序。为了解决这个问题,引入了feature_test_macros。当程序执行时#define _XOPEN_SOURCE 500,意味着它已为 POSIX 标准做好准备,并且该版本中 POSIX 引入的代码和符号之间没有冲突。

功能测试宏不仅仅是“我的程序想要使用这些功能”,最重要的是“我的程序与这些功能没有冲突”,这更重要,让现有程序继续运行。


以上是为什么我们需要功能测试宏?的全部内容。
THE END
分享
二维码
< <上一篇
下一篇>>