首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >mkdtemp需要unistd.h的_DARWIN_C_SOURCE

mkdtemp需要unistd.h的_DARWIN_C_SOURCE
EN

Stack Overflow用户
提问于 2012-07-11 20:18:58
回答 2查看 1.7K关注 0票数 2

我有点困惑。我有一个项目,我用它来编译

代码语言:javascript
复制
CFLAGS=-g -O2 -Wall -Wextra -Isrc/main -pthread -rdynamic -DNDEBUG $(OPTFLAGS) -D_FILE_OFFSET_BITS=64 -D_XOPEN_SOURCE=700

现在我想使用mkdtemp,因此包括unistd.h

代码语言:javascript
复制
char *path = mkdtemp(strdup("/tmp/test-XXXXXX"));

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

代码语言:javascript
复制
warning: implicit declaration of function ‘mkdtemp’
warning: initialization makes pointer from integer without a cast

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

问题1:模板是strdup()**ed ,结果是非空的.这究竟是如何导致EXC_BAD_ACCESS?**的?

现在深入兔子洞。我们把警告处理掉。通过检查unistd.h,我发现预处理器隐藏了声明。

代码语言:javascript
复制
#if     !defined(_POSIX_C_SOURCE) || defined(_DARWIN_C_SOURCE)
...
char    *mkdtemp(char *);
...
#endif

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

代码语言:javascript
复制
 Standard C Library (libc, -lc)
 #include <unistd.h>

从build中删除_XOPEN_SOURCE是在OSX上工作的,但是它在Linux下无法编译

代码语言:javascript
复制
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:您将如何解决这个问题?

我发现的唯一解决办法是,在#undef _POSIX_C_SOURCE之前,在unistd.h包括感觉像一个丑陋的黑客的...but之前。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2012-07-11 23:57:21

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

问题1:模板是str达普()ed,结果是非空的。这究竟是如何导致EXC_BAD_ACCESS的呢?

正如上面的警告所告诉你的:

警告:函数“mkdtemp”的隐式声明

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

警告:初始化使指针在没有强制转换的情况下从整数生成。

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

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

这就是为什么你不能忽视警告。

票数 2
EN

Stack Overflow用户

发布于 2012-07-12 00:02:52

关于第二个问题:

问题2:那么你会如何解决这个问题呢?

您的问题是您正在显式地传递-D_XOPEN_SOURCE=700,但是您使用的是一个函数mkdtemp,它没有在您所要求的标准中定义。这意味着您的代码不应该工作。它在linux上工作并不意味着您的代码是正确的或可移植的,只是您碰巧在一个平台上幸运。

因此,有两种很明显的方法可以解决这个问题:

  1. 如果要使用_XOPEN_SOURCE=700,请重写代码,仅使用该标准中的函数。
  2. 如果您只将_XOPEN_SOURCE=700添加为一个您并不真正理解的黑客,因为它似乎修复了linux上的其他一些问题,那么在linux上找到解决该问题的正确方法。

结果可能是在一个或另一个平台上有一个bug,所以没有正确的方法来修复它。或者,更有可能的是,您使用的是非标准函数的组合,这些函数可以在不同的平台上压缩,每个平台上都有不同的标志集。在这种情况下,Makefile (或其他驱动构建的工具)必须将不同的标志传递给不同平台上的编译器。对于跨平台项目来说,这是非常典型的;只是庆幸您只需要担心一个标志,而不是构建价值3000行的autoconf。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/11440787

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档