mkdtemp需要unistd.h的_DARWIN_C_源
我有点困惑。我有一个我用它编译的项目mkdtemp需要unistd.h的_DARWIN_C_源,c,linux,macos,posix,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: im
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
返回非空路径访问时,它会导致EXC\u BAD\u访问
问题1:模板为strdup()
ed,结果为非空。这究竟是如何导致EXC\u坏访问的?
现在在兔子洞的下面。让我们摆脱这些警告吧。检查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>
问题2:那么您将如何解决这个问题?
我找到的唯一修复方法是在
unistd.h
包含之前添加#undef
\u POSIX\u C\u源代码……但这感觉像是一个丑陋的黑客行为。您在这里问了两个问题,我只想回答第一个问题:
问题1:模板是strdup()的,结果是非空的。这究竟是如何导致EXC\u坏访问的
正如上面的警告告诉您的:
警告:函数“mkdtemp”的隐式声明
这意味着它找不到mkdtemp
的声明。根据C规则,这是允许的,但它假设函数返回int
警告:初始化将指针从整数转换为不带强制转换的整数
您已经告诉编译器“我有一个返回int的函数,我想将值存储在char*中”。它警告你这是个坏主意。您仍然可以这样做,因此它可以编译
但是想想在运行时会发生什么。链接到的实际代码返回64位字符*。然后,代码将其视为32位int,必须将其转换为64位char*。这样做的可能性有多大
这就是为什么您不忽略警告。现在来看第二个问题: 问题2:那么你将如何解决这个问题 您的问题是您显式地传递了-D_XOPEN_SOURCE=700,但您使用的是一个函数mkdtemp,该函数在您要求的标准中没有定义。这意味着你的代码不应该工作。它在linux上工作的事实并不意味着您的代码是正确的或可移植的,只是您碰巧在一个平台上获得了好运 因此,有两种非常明显的方法来解决这个问题:
结果可能是某个平台上有一个bug,所以没有正确的方法来修复它。或者,更可能的情况是,您正在使用非标准函数的组合,这些函数可以在不同的平台上压缩,每个平台上都有一组不同的标志。在这种情况下,您的Makefile(或任何驱动构建的东西)必须在不同的平台上向编译器传递不同的标志。这对于跨平台项目来说非常典型;很高兴您只需要担心一个标志,并且没有构建3000行的autoconf。mkdtemp不是基本的POSIX——根据它在扩展API中的描述。Segfault:你确定你传递的是char*而不是const char*?我知道
mkdtemp
不是基本POSIX。但似乎\u XOPEN\u SOURCE
导致定义\u POSIX\u C\u SOURCE
。仍然希望使用mkdtemp
和ftw
API。至于const char*
请参见上文。它是通过strdup
复制的文本。所以这应该没问题。@H2CO3呃,那里的CX实际上意味着它在POSIX中,而不是在ANSI C中。问题是OSX显然不支持它添加的POSIX版本。我只添加了\u XOPEN\u SOURCE
,因为我想使用ftw
API。显然,这也迫使\u POSIX\u C\u SOURCE
。什么是标准?linux的手册页有很多信息……最近的OpenGroup标准()的第1节和第2.2节也是如此。但一切都在一个地方?可悲的是,据我所知不是这样。(此外,linux和OS X都包含许多扩展,这些扩展可能在下一个标准中超出了它们当前支持的扩展,等等)同时,FTW在XOpen 7中并不是新的—事实上,它在XOpen 7中被标记为过时—所以我不确定这是引入它的正确方式。首先—感谢链接!非常有用<代码>ftw是否标记为已过时?叹息开罐——虫子——到处都是。最初我使用的是fts
API,但在Linux上编译时,我最终遇到了#error“不能与-D_FILE_OFFSET_BITS==64”
IIRC一起使用,fts是一个BSD扩展,Linux已经复制了它,但它仍然没有登录到POSIX中,这意味着即使它起作用,您最终可能会得到“可移植”到Linux和*BSD的代码(包括OSX)但是没有其他地方,这是欺骗你自己的好方法…这里令人悲伤的答案是没有完全可移植的替代方案。这意味着你将不得不进行一些可移植性黑客攻击。在Makefile中进行一行平台检查比大多数项目必须处理的痛苦要小得多…考虑到我只关心Linux和OS X在这个阶段-现在还可以。不使用文件偏移量是一个可以让我逃离“地狱”的妥协。谢谢你们的输入,伙计们。因为另一个问题似乎没有简单的答案,我接受这个问题。
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)