当我将标志“-std=c99”添加到 minwg32 时会发生什么?
What happens when I add the flag "-std=c99" to minwg32?
在 Windows 上 Code::Block 版本 16.01 和 minwg32 gcc。
代码如下:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <stdio.h>
#include <time.h>
#include <pthread.h>
#include <semaphore.h>
#include <unistd.h>
#include <windows.h>
#ifdef WIN32
#if defined(_MSC_VER) || defined(_MSC_EXTENSIONS)
#define DELTA_EPOCH_IN_MICROSECS 11644473600000000Ui64
#else
#define DELTA_EPOCH_IN_MICROSECS 11644473600000000ULL
#endif
#endif
struct timezone_ex
{
int tz_minuteswest; /* minutes W of Greenwich */
int tz_dsttime; /* type of dst correction */
};
int gettimeofday_ex(struct timeval *tv, struct timezone_ex *tz);
/********************************************//**
* \brief
*
* \param tv struct timeval*
* \param tz struct timezone*
* \return int
*
***********************************************/
int gettimeofday_ex(struct timeval *tv, struct timezone_ex *tz)
{
FILETIME ft;
unsigned long long tmpres = 0;
static int tzflag;
if (tv)
{
GetSystemTimeAsFileTime(&ft);
tmpres |= ft.dwHighDateTime;
tmpres <<= 32;
tmpres |= ft.dwLowDateTime;
/*converting file time to unix epoch*/
tmpres /= 10; /*convert into microseconds*/
tmpres -= DELTA_EPOCH_IN_MICROSECS;
tv->tv_sec = (long)(tmpres / 1000000UL);
tv->tv_usec = (long)(tmpres % 1000000UL);
}
if (tz)
{
if (!tzflag)
{
_tzset();
tzflag++;
}
tz->tz_minuteswest = _timezone / 60;
tz->tz_dsttime = _daylight;
}
return 0;
}
int main()
{
struct timeval t;
gettimeofday_ex(&t, NULL);
printf("t.tv_sec=%d, t.tz_dsttime=%d;\r\n", t.tv_sec, t.tv_usec);
return 0;
}
当我在没有标志 -std=c99 的情况下编译代码时,它可以工作;
这是构建日志:
-------------- Build: Debug in TestForStudy (compiler: GNU GCC Compiler)---------------
mingw32-gcc.exe -g -c D:\WorkSpace\iSource\TestForStudy\main.c -o
obj\Debug\main.o mingw32-g++.exe -o bin\Debug\TestForStudy.exe
obj\Debug\main.o -lpthread Output file is
bin\Debug\TestForStudy.exe with size 40.23 KB Process terminated with
status 0 (0 minute(s), 0 second(s)) 0 error(s), 0 warning(s) (0
minute(s), 0 second(s))
但是,如果我添加标志 -std=c99,并再次重建它,我会收到错误消息:
-------------- Build: Debug in TestForStudy (compiler: GNU GCC Compiler)---------------
mingw32-gcc.exe -std=c99 -g -c
D:\WorkSpace\iSource\TestForStudy\main.c -o obj\Debug\main.o
mingw32-g++.exe -o bin\Debug\TestForStudy.exe obj\Debug\main.o
-lpthread D:\WorkSpace\iSource\TestForStudy\main.c: In function 'gettimeofday_ex': D:\WorkSpace\iSource\TestForStudy\main.c:60:13:
warning: implicit declaration of function '_tzset'
[-Wimplicit-function-declaration]
_tzset();
^ D:\WorkSpace\iSource\TestForStudy\main.c:63:30: error: '_timezone' undeclared (first use in this function)
tz->tz_minuteswest = _timezone / 60;
^ D:\WorkSpace\iSource\TestForStudy\main.c:63:30: note: each undeclared
identifier is reported only once for each function it appears in
D:\WorkSpace\iSource\TestForStudy\main.c:64:26: error: '_daylight'
undeclared (first use in this function)
tz->tz_dsttime = _daylight;
^ Process terminated with status 1 (0 minute(s), 0 second(s)) 2 error(s), 1 warning(s) (0 minute(s), 0
second(s))
我用谷歌搜索了一些关于这个问题的东西,但没有得到任何有用的信息。我不知道是我的代码有问题还是 minwg32 有问题?
任何人都可以给我任何关于这个问题的提示吗?
谢谢!
编辑:
在我post这个问题之后,我看了这个问题:
Socket undeclared when i use -std=c99 [c]
好像是同样的问题,我尝试把-std=c99改成-std=gnu99,又可以了
那么,这是带有标志 c99 的 minwg32 中的错误吗?因为我觉得不管用哪个flag,代码都没有错误,所有的flag都不应该有错误。
当您在命令行中指定特定的 C 标准版本时,标准头文件的所有非标准内容都会得到 "hidden"。 tzset
就是这样。它在 <time.h>
中声明,但它不是 <time.h>
的标准成员。标准库没有这个功能。
如果您希望编译器在 <time.h>
中看到它并使用它,请指定 -std=gnu99
而不是 -std=c99
。如果您希望您的程序符合标准,请使用 -std=c99
而忘记 tzset
。要么这样,要么那样。
添加到 AnT 的回答:C 标准库有 不同的 扩展,一些在 POSIX 中指定,一些是 BSD 扩展,一些来自 System V Unix,当然还有 GNU 特定的扩展,仅举几例。
我个人建议始终将 -std
标志设置为 ISO C 标准之一进行编译,最好是最新的 (-std=c11
)。然后,如果您需要使用扩展,请在 #include
任何标准 headers 之前为需要它们的文件定义 feature test macro 启用它们,例如在使用 POSIX.1-2001
函数的文件中,使用第一行:
#define _POSIX_C_SOURCE 200112L
此建议的原因是明确哪里和哪个语言扩展被使用。这简化了以后移植到不同平台的过程。它还鼓励您将依赖于扩展的代码与完全可移植的代码清楚地分开。
在 Windows 上 Code::Block 版本 16.01 和 minwg32 gcc。
代码如下:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <stdio.h>
#include <time.h>
#include <pthread.h>
#include <semaphore.h>
#include <unistd.h>
#include <windows.h>
#ifdef WIN32
#if defined(_MSC_VER) || defined(_MSC_EXTENSIONS)
#define DELTA_EPOCH_IN_MICROSECS 11644473600000000Ui64
#else
#define DELTA_EPOCH_IN_MICROSECS 11644473600000000ULL
#endif
#endif
struct timezone_ex
{
int tz_minuteswest; /* minutes W of Greenwich */
int tz_dsttime; /* type of dst correction */
};
int gettimeofday_ex(struct timeval *tv, struct timezone_ex *tz);
/********************************************//**
* \brief
*
* \param tv struct timeval*
* \param tz struct timezone*
* \return int
*
***********************************************/
int gettimeofday_ex(struct timeval *tv, struct timezone_ex *tz)
{
FILETIME ft;
unsigned long long tmpres = 0;
static int tzflag;
if (tv)
{
GetSystemTimeAsFileTime(&ft);
tmpres |= ft.dwHighDateTime;
tmpres <<= 32;
tmpres |= ft.dwLowDateTime;
/*converting file time to unix epoch*/
tmpres /= 10; /*convert into microseconds*/
tmpres -= DELTA_EPOCH_IN_MICROSECS;
tv->tv_sec = (long)(tmpres / 1000000UL);
tv->tv_usec = (long)(tmpres % 1000000UL);
}
if (tz)
{
if (!tzflag)
{
_tzset();
tzflag++;
}
tz->tz_minuteswest = _timezone / 60;
tz->tz_dsttime = _daylight;
}
return 0;
}
int main()
{
struct timeval t;
gettimeofday_ex(&t, NULL);
printf("t.tv_sec=%d, t.tz_dsttime=%d;\r\n", t.tv_sec, t.tv_usec);
return 0;
}
当我在没有标志 -std=c99 的情况下编译代码时,它可以工作; 这是构建日志:
-------------- Build: Debug in TestForStudy (compiler: GNU GCC Compiler)---------------
mingw32-gcc.exe -g -c D:\WorkSpace\iSource\TestForStudy\main.c -o obj\Debug\main.o mingw32-g++.exe -o bin\Debug\TestForStudy.exe obj\Debug\main.o -lpthread Output file is bin\Debug\TestForStudy.exe with size 40.23 KB Process terminated with status 0 (0 minute(s), 0 second(s)) 0 error(s), 0 warning(s) (0 minute(s), 0 second(s))
但是,如果我添加标志 -std=c99,并再次重建它,我会收到错误消息:
-------------- Build: Debug in TestForStudy (compiler: GNU GCC Compiler)---------------
mingw32-gcc.exe -std=c99 -g -c D:\WorkSpace\iSource\TestForStudy\main.c -o obj\Debug\main.o mingw32-g++.exe -o bin\Debug\TestForStudy.exe obj\Debug\main.o -lpthread D:\WorkSpace\iSource\TestForStudy\main.c: In function 'gettimeofday_ex': D:\WorkSpace\iSource\TestForStudy\main.c:60:13: warning: implicit declaration of function '_tzset' [-Wimplicit-function-declaration] _tzset(); ^ D:\WorkSpace\iSource\TestForStudy\main.c:63:30: error: '_timezone' undeclared (first use in this function) tz->tz_minuteswest = _timezone / 60; ^ D:\WorkSpace\iSource\TestForStudy\main.c:63:30: note: each undeclared identifier is reported only once for each function it appears in D:\WorkSpace\iSource\TestForStudy\main.c:64:26: error: '_daylight' undeclared (first use in this function) tz->tz_dsttime = _daylight; ^ Process terminated with status 1 (0 minute(s), 0 second(s)) 2 error(s), 1 warning(s) (0 minute(s), 0 second(s))
我用谷歌搜索了一些关于这个问题的东西,但没有得到任何有用的信息。我不知道是我的代码有问题还是 minwg32 有问题?
任何人都可以给我任何关于这个问题的提示吗? 谢谢!
编辑:
在我post这个问题之后,我看了这个问题: Socket undeclared when i use -std=c99 [c]
好像是同样的问题,我尝试把-std=c99改成-std=gnu99,又可以了
那么,这是带有标志 c99 的 minwg32 中的错误吗?因为我觉得不管用哪个flag,代码都没有错误,所有的flag都不应该有错误。
当您在命令行中指定特定的 C 标准版本时,标准头文件的所有非标准内容都会得到 "hidden"。 tzset
就是这样。它在 <time.h>
中声明,但它不是 <time.h>
的标准成员。标准库没有这个功能。
如果您希望编译器在 <time.h>
中看到它并使用它,请指定 -std=gnu99
而不是 -std=c99
。如果您希望您的程序符合标准,请使用 -std=c99
而忘记 tzset
。要么这样,要么那样。
添加到 AnT 的回答:C 标准库有 不同的 扩展,一些在 POSIX 中指定,一些是 BSD 扩展,一些来自 System V Unix,当然还有 GNU 特定的扩展,仅举几例。
我个人建议始终将 -std
标志设置为 ISO C 标准之一进行编译,最好是最新的 (-std=c11
)。然后,如果您需要使用扩展,请在 #include
任何标准 headers 之前为需要它们的文件定义 feature test macro 启用它们,例如在使用 POSIX.1-2001
函数的文件中,使用第一行:
#define _POSIX_C_SOURCE 200112L
此建议的原因是明确哪里和哪个语言扩展被使用。这简化了以后移植到不同平台的过程。它还鼓励您将依赖于扩展的代码与完全可移植的代码清楚地分开。