使用-std=c99时的隐式声明

15

我得到了这个警告:(-std=c99 -pedantic)

warning: implicit declaration of functionstrndup[-Wimplicit-function-declaration]

但是我正在导入这些库:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

那又怎样?! :(


// file.c:
    #include "file.h"
    strndup(...)
// file.h:
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>

你能展示一下如何调用 strndup 吗?它是被调用而不是被导入的,这些都是 C 头文件而不是库。 - iabdalkader
@mux:它的名称似乎并不重要,问题很可能是GCC没有使用指定的标志提供此函数声明(或在MinGW的情况下根本没有提供)。 - Niklas B.
你的程序尽管有警告,但是否能链接成功呢?正如上面两条评论所说,无论是头文件还是库中,MinGW 中都没有 strndup。 - JimR
@NiklasB。是的,你说得对,我认为上下文可能是相关的,抱歉。 - iabdalkader
4个回答

31
问题在于您使用了-std=c99选项。由于strndup()不是C99的一部分,而你又要求编译器进入符合规范的模式,它就不会提供它的原型。当然,它仍然链接,因为你的C库有它。
虽然你可以通过自己指定特性宏来劝说gcc提供它,但我认为在C99兼容模式下要求GNU扩展并没有太多意义。gcc已经为此提供了一种模式,这将解决你的警告:-std=gnu99

11
gnu99不是解决方案,定义正确的特性测试宏才是解决方案。如果要使用POSIX定义的接口,则必须在包含任何头文件之前将_POSIX_C_SOURCE定义为所需版本(200809L)(或者如果您还想使用完整的XSI选项,则定义_XOPEN_SOURCE)。 - R.. GitHub STOP HELPING ICE
我非常确定strndup()也不是POSIX标准。根据手册,它是GNU的扩展。为什么不使用gnu99模式,而要使用特性测试宏来启用它呢? - FatalError
2
Austin Group 持不同意见:http://pubs.opengroup.org/onlinepubs/9699919799/functions/strndup.html - R.. GitHub STOP HELPING ICE
1
至于为什么要以正确的方式进行操作,答案是它是可移植的。定义正确的特性测试宏将使您的程序在任何符合POSIX标准的系统上运行。使用“gnu99”将使您的程序在Linux + glibc上运行。实际上,“-std = gnu99”的目的主要是启用GNU C 编译器扩展,在GCC可用的任何地方都可以工作,但GNU libc特定的扩展将不会普遍可用。 - R.. GitHub STOP HELPING ICE
很有趣,感谢提供链接。您关于可移植性的论点很有道理。我的主要观点是,如果你打算使用GNU扩展函数,最好就总体启用GNU扩展 - 但似乎我的手册需要更新。如果我们只想访问该函数,那么我同意您所说的这个(即解决方案)可能更好。 - FatalError

9

我的man strndup说:

glibc的功能测试宏要求(请参阅feature_test_macros(7)):
strdup(): _SVID_SOURCE || _BSD_SOURCE || _XOPEN_SOURCE >= 500 || _XOPEN_SOURCE && _XOPEN_SOURCE_EXTENDED || /* 自glibc 2.12起: */ _POSIX_C_SOURCE >= 200809L strndup(): 自glibc 2.10起: _POSIX_C_SOURCE >= 200809L || _XOPEN_SOURCE >= 700 在glibc 2.10之前: _GNU_SOURCE strdupa(),strndupa():_GNU_SOURCE

所以我需要在您的文件中的第一个#include之前,例如#define _POSIX_C_SOURCE 200809L
请参阅man 7 feature_test_macros


8

strndup是GNU扩展,所以你需要在命令行中使用-D_GNU_SOURCE进行编译,或者在#include行之前在源文件中插入#define _GNU_SOURCE 1


1

这也发生在我身上,我添加了 #define _XOPEN_SOURCE 500 ,警告消失了。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接