为什么不sys / stat。用-std=c1x来定义ino_t ?

时间:2022-09-06 20:06:22

I'm experiencing a strange problem with some C code I am writing. Consider the following code:

我正在经历一个奇怪的问题,我写的一些C代码。考虑下面的代码:

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

According to POSIX.1-2008, the header file <sys/stat.h> defines ino_t1:

根据POSIX.1-2008,头文件 定义ino_t1:

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_t、blksize_t、dev_t、ino_t、mode_t、nlink_t、uid_t、gid_t、off_t和time_t类型,如

This happens when I try to compile the source code above places in a file test.c on my Linux system:

当我尝试在文件测试中的位置上编译源代码时,就会发生这种情况。c在我的Linux系统上:

$ 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的定义不具有启示意义?

2 个解决方案

#1


3  

My manual page of fstat says to also include sys/types.h, and that solves the problem for me. The definition of ino_t in sys/stat.h is protected with the feature macros __USE_XOPEN and __USE_XOPEN2K. The definition in sys/types.h is not protected that way.

我的fstat手册页上还提到了sys/types。h,这就解决了我的问题。ino_t在sys/stat中的定义。使用宏__USE_XOPEN和__USE_XOPEN2K来保护h。定义在sys /类型。h不受保护。

The manual page also says to include unistd.h, but that wasn't necessary to solve your problem.

手册页还说,包括unistd。但那不是解决你问题的必要条件。

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.这个宏是由gcc(1)在调用时隐式定义的,例如,-std=c99或-ansi标志。

I guess this means that any XOPEN features are also switched off. I could however not find any description of that.

我想这意味着任何XOPEN特性也都被关闭了。但是我没有找到任何关于它的描述。

P.S. 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. If it were described anywhere, then I would expect it in that manual page indeed.

注:似乎R . .(见下文)感觉这也是在feature_test_macros的手册页中描述的,但是我有限的大脑无法找到准确的措辞,所以我想把它留给读者作为练习。如果它在任何地方被描述,那么我就会期望它在那个手册页中。

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.

你应该包括所有包含在手册页中提到的文件,而不是试图反向工程师,那些可能不需要。

#2


0  

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. They do not, by themselves, tell GCC to be strictly conforming (e.g. diagnose all use of GNU extensions). If you want strict conformance you must also give the options -Wall -Wpedantic.

许多人没有正确理解-std=cXX选项的影响。它们本身并没有告诉GCC要严格遵守(例如,诊断所有使用GNU扩展)。如果您想要严格的一致性,您还必须给出选项-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. This one is a Good Thing; application-namespace predefined macros are confusing at best, and at worst, break legitimate code. However, it has been known to break system header files that are still looking for those macros.

    在-std=cXX模式中禁用了应用程序名称空间中特定于系统的预定义宏。这是一件好事;应用程序名称空间预定义宏在最好情况下是令人困惑的,在最坏的情况下,会破坏合法的代码。然而,众所周知,它会破坏仍然在寻找这些宏的系统头文件。

  2. Trigraphs are enabled in -std=cXX modes and disabled in -std=gnuXX modes. 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.

    在std=cXX模式中启用Trigraphs,在-std=gnuXX模式中禁用。你不希望三字母词;当它们被发明的时候它们已经过时了,而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. (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. 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.

    在-std=cXX模式下,GNU libc将尝试将超出指定的C标准的扩展的数量最小化。(注意:GCC可以使用的许多其他C库不会这样做。)在像sys/stat这样的头文件中。这不是C标准的一部分,这意味着“只公开我们支持的最古老版本中存在的特性”,这通常是非常古老和有限的,比如POSIX.1-1993。这就是绊倒你的原因。您可以通过定义特性测试宏来绕过它,直接使用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. 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).

如果你从头编写一个新的C程序,我建议您使用- wall和-Wpedantic(也许一堆其他- w开关)但我不建议使用化cXX,作为唯一的积极作用是关闭系统特定的预定义了,可以打破系统头文件。直接使用_GNU_SOURCE或等效项,而不是试图找到一个_POSIX_C_SOURCE或_XOPEN_SOURCE设置,它可以为您提供所需的一切(特别是如果您或使用第三方代码打包,可能会使用诸如gettimeofday之类的不受欢迎但仍然很普通的函数),这几乎总是比使用futz更省事。

#1


3  

My manual page of fstat says to also include sys/types.h, and that solves the problem for me. The definition of ino_t in sys/stat.h is protected with the feature macros __USE_XOPEN and __USE_XOPEN2K. The definition in sys/types.h is not protected that way.

我的fstat手册页上还提到了sys/types。h,这就解决了我的问题。ino_t在sys/stat中的定义。使用宏__USE_XOPEN和__USE_XOPEN2K来保护h。定义在sys /类型。h不受保护。

The manual page also says to include unistd.h, but that wasn't necessary to solve your problem.

手册页还说,包括unistd。但那不是解决你问题的必要条件。

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.这个宏是由gcc(1)在调用时隐式定义的,例如,-std=c99或-ansi标志。

I guess this means that any XOPEN features are also switched off. I could however not find any description of that.

我想这意味着任何XOPEN特性也都被关闭了。但是我没有找到任何关于它的描述。

P.S. 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. If it were described anywhere, then I would expect it in that manual page indeed.

注:似乎R . .(见下文)感觉这也是在feature_test_macros的手册页中描述的,但是我有限的大脑无法找到准确的措辞,所以我想把它留给读者作为练习。如果它在任何地方被描述,那么我就会期望它在那个手册页中。

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.

你应该包括所有包含在手册页中提到的文件,而不是试图反向工程师,那些可能不需要。

#2


0  

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. They do not, by themselves, tell GCC to be strictly conforming (e.g. diagnose all use of GNU extensions). If you want strict conformance you must also give the options -Wall -Wpedantic.

许多人没有正确理解-std=cXX选项的影响。它们本身并没有告诉GCC要严格遵守(例如,诊断所有使用GNU扩展)。如果您想要严格的一致性,您还必须给出选项-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. This one is a Good Thing; application-namespace predefined macros are confusing at best, and at worst, break legitimate code. However, it has been known to break system header files that are still looking for those macros.

    在-std=cXX模式中禁用了应用程序名称空间中特定于系统的预定义宏。这是一件好事;应用程序名称空间预定义宏在最好情况下是令人困惑的,在最坏的情况下,会破坏合法的代码。然而,众所周知,它会破坏仍然在寻找这些宏的系统头文件。

  2. Trigraphs are enabled in -std=cXX modes and disabled in -std=gnuXX modes. 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.

    在std=cXX模式中启用Trigraphs,在-std=gnuXX模式中禁用。你不希望三字母词;当它们被发明的时候它们已经过时了,而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. (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. 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.

    在-std=cXX模式下,GNU libc将尝试将超出指定的C标准的扩展的数量最小化。(注意:GCC可以使用的许多其他C库不会这样做。)在像sys/stat这样的头文件中。这不是C标准的一部分,这意味着“只公开我们支持的最古老版本中存在的特性”,这通常是非常古老和有限的,比如POSIX.1-1993。这就是绊倒你的原因。您可以通过定义特性测试宏来绕过它,直接使用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. 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).

如果你从头编写一个新的C程序,我建议您使用- wall和-Wpedantic(也许一堆其他- w开关)但我不建议使用化cXX,作为唯一的积极作用是关闭系统特定的预定义了,可以打破系统头文件。直接使用_GNU_SOURCE或等效项,而不是试图找到一个_POSIX_C_SOURCE或_XOPEN_SOURCE设置,它可以为您提供所需的一切(特别是如果您或使用第三方代码打包,可能会使用诸如gettimeofday之类的不受欢迎但仍然很普通的函数),这几乎总是比使用futz更省事。