c - 为什么我们需要功能测试宏?
问题描述
通过阅读-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 在该版本中引入的代码和符号之间没有冲突。
功能测试宏不仅仅是“我的程序要使用这些功能”,最重要的是“我的程序与这些功能没有冲突”,更重要的是,让现有的程序继续运行。
推荐阅读
- shell - 不要附加视频 id youtube-dl
- c# - 如何获取用户的当前 ID 以传递给 _Layout ASP.NET Core?
- unity3d - Graphics.RenderTexture() 导致额外的图像出现在画布上
- laravel - 有没有其他方法可以解决这个 PostsController 在 Laravel 8 上不起作用的问题?
- python - 如何从excel文件的第一列获取值作为数组?
- typescript - Lerna、yarn 和 Typescript:找不到模块或其对应的类型声明
- nuxt.js - NuxtJS - 在页面组件中与 asyncData 并行运行 nuxtServerInit
- python - Python:在复杂的嵌套字典中查找并返回特定字典
- javascript - 如果我们有重复的代码,如何获取文本
- apache-spark-sql - Spark SQL 选择不适用于 DataBricks