c - mkdtemp 需要 _DARWIN_C_SOURCE for unistd.h

标签 c linux macos posix

我有点困惑。我有一个编译项目

CFLAGS=-g -O2 -Wall -Wextra -Isrc/main -pthread -rdynamic -DNDEBUG $(OPTFLAGS) -D_FILE_OFFSET_BITS=64 -D_XOPEN_SOURCE=700

现在我想使用 mkdtemp 并因此包含 unistd.h

char *path = mkdtemp(strdup("/tmp/test-XXXXXX"));

在 MacOSX 上,编译会给出一些警告

warning: implicit declaration of function ‘mkdtemp’
warning: initialization makes pointer from integer without a cast

但是编译通过。虽然 mkdtemp 确实返回非 NULL 路径,但访问它会导致 EXC_BAD_ACCESS。

问题 1:模板经过 strdup() 处理,结果为非 NULL。这到底是如何导致 EXC_BAD_ACCESS 的?

现在进一步深入兔子洞。让我们摆脱警告。检查 unistd.h 我发现预处理器隐藏了声明。

#if     !defined(_POSIX_C_SOURCE) || defined(_DARWIN_C_SOURCE)
...
char    *mkdtemp(char *);
...
#endif

-D_DARWIN_C_SOURCE 添加到构建中可以使所有问题消失,但留给我一个特定于平台的构建。 10.6 手册页只是说

 Standard C Library (libc, -lc)
 #include <unistd.h>

从构建中删除 _XOPEN_SOURCE 在 OSX 上可以工作,但在 Linux 下无法编译

warning: ‘struct FTW’ declared inside parameter list
warning: its scope is only this definition or declaration, which is probably not what you want
In function ‘tmp_remove’:
warning: implicit declaration of function ‘nftw’
error: ‘FTW_DEPTH’ undeclared (first use in this function)
error: (Each undeclared identifier is reported only once
error: for each function it appears in.)
error: ‘FTW_PHYS’ undeclared (first use in this function)

问题 2:那么您将如何解决这个问题?

我发现的唯一修复方法是在 unistd.h 之前包含 #undef _POSIX_C_SOURCE ...但这感觉像是一个丑陋的黑客。

最佳答案

您在这里问了两个问题,我只回答第一个问题:

Question 1: The template is strdup()ed and the result is non-NULL. How on earth can this result in an EXC_BAD_ACCESS?

正如上面的警告告诉您的那样:

warning: implicit declaration of function ‘mkdtemp’

这意味着它找不到 mkdtemp 的声明。根据 C 规则,这是允许的,但假设该函数返回一个 int。

warning: initialization makes pointer from integer without a cast

您已经告诉编译器“我有一个返回 int 的函数,并且我想将值存储在 char* 中”。它警告您这是一个坏主意。您仍然可以这样做,因此它可以编译。

但是想想运行时会发生什么。您链接到的实际代码返回 64 位 char*。然后您的代码将其视为 32 位 int,必须将其转换为 64 位 char*。这可行的可能性有多大?

这就是为什么您不忽略警告的原因。

关于c - mkdtemp 需要 _DARWIN_C_SOURCE for unistd.h,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11440787/

相关文章:

c - 如何阻止 GCC 在 snprintf() 调用中提示 "directive output may be truncated"?

c - 使用分散聚集处理短读/写的技术?

c - 从服务生成 GUI

c++ - 突然崩溃后,程序中的所有指针变量都被删除了吗?

c - C 中具有负索引的二维数组

c - 将 c 中 arg 的输入值添加到数独求解器的数组中

java - Mac 是否支持零复制原理

php - 安装的 MacPorts PHP,现在无法与 MySQL 交互 - Mac OS X

macos - 如何在英式键盘上的 TextMate for Mac 中插入哈希符号?

c++ - std::runtime_error: resolve: 在 boost::asio 中找不到主机(权威)