麻烦包括strptime()的函数声明

时间:2017-04-17 22:50:56

标签: c

有一个时间日期字符串我想转换为tm对象。 Google告诉我,POSIX(但不是C)标准包含一个名为strptime()的功能,可以完成这项工作。

该手册页说明它位于<time.h>,我需要在包含#define _XOPEN_SOURCE文件之前加入<time.h>。很容易。

但我仍然得到编译器的隐式声明警告。我打开了/usr/include/time.h并找到了函数声明:

 # ifdef __USE_XOPEN
/* Parse S according to FORMAT and store binary time information in TP.
   The return value is a pointer to the first unparsed character in S.  */
extern char *strptime (const char *__restrict __s,
               const char *__restrict __fmt, struct tm *__tp)
     __THROW;
#endif

所以看起来我需要#define _USE_XOPEN

除此之外也不起作用。编译器仍然没有看到声明。

任何想法。我正在使用相对较新版本的Linux(Mint)和gcc 5.4.0。

1 个答案:

答案 0 :(得分:7)

将评论转换为答案。

要解决此问题,您的选项包括在GCC命令行上使用-std=gnu11代替-std=c11,或在命令行上使用#define _XOPEN_SOURCE 700或等效内容(例如-D_XOPEN_SOURCE=700) 。 700识别POSIX 2008; 600或500标识POSIX或X / Open的早期版本。

理论上,您也可以使用_POSIX_C_SOURCE 200809L(请参阅POSIX Compilation environment),但这并不会暴露_XOPEN_SOURCE 700所暴露的所有内容,因此通常最好使用后者。< / p>

请注意,strptime()的POSIX规范注释为XSI扩展,这意味着您必须设置_XOPEN_SOURCE;单独设置_POSIX_C_SOURCE是不够的。

测试代码

此测试代码打印strptime函数的地址;如果未声明strptime(),则无法编译。

#define _XOPEN_SOURCE 700
#include <time.h>
#include <stdio.h>

int main(void)
{
    printf("%p\n", (void *)strptime);
    return 0;
}

应该使用gcc -std=c11 -Wall -c test-strptime.c为您编译。如果将-ansi添加到选项中,则将标准重置为C90。 GCC 5.4.0应该默认为C11(有效-std=gnu11),除非有人在您正在使用的GCC构建中做了一些可怕的事情(这不太可能)。

请注意,编译器取消设置,然后根据__USE_XOPEN等设置设置_XOPEN_SOURCE并尝试手动设置它无法可靠地运行。

职位重要

您必须在包含第一个系统标头之前指定#define _XOPEN_SOURCE 700(无论是直接还是间接包含)。如果在尝试设置_XOPEN_SOURCE之前包含系统标头,则已确定设置,并且有效地忽略后续操作。 POSIX说(在'编译环境'链接已经给出):

  

在编译#define由POSIX.1-2008指定的特征测试宏的应用程序时,在定义特征测试宏之前,不应包括POSIX.1-2008定义的头。此限制也适用于使用这些功能测试宏的任何实现提供的标头。如果宏的定义不在#include之前,则结果是未定义的。

一个常见的未定义结果是您完全忽略了设置/更改POSIX版本的尝试。