简体   繁体   English

为什么sys / stat.h不使用-std = c1x定义ino_t?

[英]Why won't sys/stat.h define ino_t with -std=c1x?

I'm experiencing a strange problem with some C code I am writing. 我正在编写的一些C代码遇到一个奇怪的问题。 Consider the following code: 考虑以下代码:

#include <sys/stat.h>
ino_t inode;

According to POSIX.1-2008 , the header file <sys/stat.h > defines ino_t 1 : 根据POSIX.1-2008 ,头文件<sys / stat.h >定义了ino_t 1

The <sys/stat.h> header shall define the blkcnt_t , blksize_t , dev_t , ino_t , mode_t , nlink_t , uid_t , gid_t , off_t , and time_t types as described in <sys/types.h> . <sys / stat.h>标头应定义blkcnt_tblksize_tdev_tino_tmode_tnlink_tuid_tgid_toff_ttime_t类型,如<sys / types.h>中所述

This happens when I try to compile the source code above places in a file test.c on my Linux system: 当我尝试在Linux系统上的文件test.c中编译以上源代码时,会发生这种情况:

$ cat test.c
#include <sys/stat.h>
ino_t inode;
$ uname -srm
Linux 3.8.0-26-generic x86_64
$ lsb_release -d
Description:    Ubuntu 13.04
$ gcc -c test.c
$ gcc -std=c90 test.c
test.c:2:1: error: unknown type name 'ino_t'
$ gcc -std=c99 test.c     
test.c:2:1: error: unknown type name 'ino_t'
$ gcc -std=c1x test.c
test.c:2:1: error: unknown type name 'ino_t'

Why is the definition of ino_t not revelead when I specify any -std option? 为什么在指定任何-std选项时ino_t的定义ino_t

My manual page of fstat says to also include sys/types.h , and that solves the problem for me. 我的fstat手册页上说还包括sys/types.h ,这为我解决了问题。 The definition of ino_t in sys/stat.h is protected with the feature macros __USE_XOPEN and __USE_XOPEN2K . sys/stat.hino_t的定义受功能宏__USE_XOPEN__USE_XOPEN2K The definition in sys/types.h is not protected that way. sys/types.h的定义不受这种保护。

The manual page also says to include unistd.h , but that wasn't necessary to solve your problem. 手册页还说包含unistd.h ,但这对于解决您的问题不是必需的。

According to the manual page of feature_test_macros : 根据feature_test_macros的手册页:

__STRICT_ANSI__ ISO Standard C. This macro is implicitly defined by gcc(1) when invoked with, for example, the -std=c99 or -ansi flag. __STRICT_ANSI__ ISO标准C。使用例如-std=c99-ansi标志调用时,此宏由gcc(1)隐式定义。

I guess this means that any XOPEN features are also switched off. 我想这意味着所有XOPEN功能也都被关闭了。 I could however not find any description of that. 但是,我找不到任何描述。

PS It seems R.. (see below) feels that this is described also in the manual page of feature_test_macros , but my limited brain is not able to find the exact wording, so I'd like to leave that as an exercise to the reader. PS似乎R ..(见下文)感觉在feature_test_macros的手册页中也有介绍,但是我有限的大脑无法找到确切的用词,因此我想把它留给读者练习。 If it were described anywhere, then I would expect it in that manual page indeed. 如果在任何地方对其进行了描述,那么我确实希望在该手册页中可以找到它。

Beware that the gist of this answer is as follows: 注意此答案的要点如下:

Thou shall include all include files mentioned in a manual page and not try to reverse engineer which ones may not be needed. 您应包括手册页中提到的所有包含文件,而不要对可能不需要的文件进行反向工程。

Your program would have compiled without complaint if you had used -std=gnuXX instead of -std=cXX . 如果使用-std=gnuXX而不是-std=cXX则程序可以毫无抱怨地进行编译。

$ cc -std=c11 -fsyntax-only test.c ; echo $?
test.c:2:1: error: unknown type name ‘ino_t’; did you mean ‘__ino_t’?
1

but

$ cc -std=gnu11 -fsyntax-only test.c ; echo $?
0

Many people don't properly understand the effects of the -std=cXX options. 许多人对-std=cXX选项的效果-std=cXX They do not , by themselves, tell GCC to be strictly conforming (eg diagnose all use of GNU extensions). 他们自己并没有告诉GCC严格遵守(例如,诊断所有使用GNU扩展的信息)。 If you want strict conformance you must also give the options -Wall -Wpedantic . 如果要严格遵守,还必须提供-Wall -Wpedantic选项。

There are only three differences between a -std=cXX mode and the corresponding -std=gnuXX mode, and two of them are usually not what you want: -std=cXX模式和对应的-std=gnuXX模式之间只有三个区别,而其中两个通常不是您想要的:

  1. System-specific predefined macros in the application namespace are disabled in -std=cXX mode. -std=cXX模式下,将禁用应用程序名称空间中特定系统的预定义宏 This one is a Good Thing; 这是一件好事; application-namespace predefined macros are confusing at best, and at worst, break legitimate code. application-namespace预定义的宏充其量是令人困惑的,最坏的情况是破坏合法代码。 However, it has been known to break system header files that are still looking for those macros. 但是,已知会破坏仍在寻找这些宏的系统头文件。

  2. Trigraphs are enabled in -std=cXX modes and disabled in -std=gnuXX modes. 三合在启用-std=cXX模式和残疾人-std=gnuXX模式。 You don't want trigraphs; 你不想要三部曲; they were already obsolete when they were invented, and IMNSHO they should have been removed from the C standard a very long time ago. 它们在发明时就已经过时了,IMNSHO应该在很久以前就将它们从C标准中删除。

  3. In -std=cXX mode, GNU libc will attempt to minimize the number of extensions above and beyond the specified C standard that are visible in its headers. -std=cXX模式下,GNU libc将尝试最小化在其标头中可见的超出指定C标准的扩展数量。 (Caution: many other C libraries that GCC can be used with will not do this.) In the case of headers like sys/stat.h that aren't part of the C standard, this is taken to mean "expose only the features that were present in the oldest version of this header we support," which is often something very old and limited, like POSIX.1-1993. (警告:可以与GCC一起使用的许多其他C库都不会这样做。)对于sys/stat.h类的标头不属于C标准的情况,它的意思是“仅公开功能“我们支持的此标头的最旧版本中包含的内容”,这通常非常古老且受限制,例如POSIX.1-1993。 This is what tripped you up. 这就是让您绊倒的原因。 You can work around it by defining feature test macros to direct GNU libc to expose newer POSIX, etc. features. 您可以通过定义功能测试宏来解决该问题,以指示GNU libc公开较新的POSIX等功能。

If you are writing a new C program from scratch, I recommend you use -Wall and -Wpedantic (and probably a bunch of other -W switches ) but I do not recommend the use of -std=cXX , as the only positive effect is to turn off the system-specific predefines, and that can break system headers. 如果您是从头开始编写新的C程序,我建议您使用-Wall-Wpedantic (可能还有许多其他-W开关 ),但我建议使用-std=cXX ,因为唯一的积极效果是关闭系统特定的预定义,这可能会破坏系统头。 It is also almost always less hassle to go straight for _GNU_SOURCE or equivalent than to futz around with trying to find a _POSIX_C_SOURCE or _XOPEN_SOURCE setting that gives you everything you need (particularly if you, or third-party code you bundle, might use deprecated-but-still-commonplace functions like gettimeofday ). 这也是几乎总是少些麻烦直来直去的_GNU_SOURCE或相当于比futz周围试图找到一个_POSIX_C_SOURCE_XOPEN_SOURCE设置,为您提供所需的一切(特别是如果你或你捆绑第三方代码,可能使用deprecated-但仍然很常见的功能,例如gettimeofday )。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM