哪里可以findoff_ttypes的完整定义?
我使用TCP将文件从客户端发送到服务器。 要标记文件的结尾,我希望在实际数据之前发送文件大小。 所以我使用stat
系统调用来查找文件的大小。 这是typesoff_t
。 我想知道它占用了多less字节,以便我可以在服务器端正确读取它。 它在<sys/types.h>
定义。 但是我不明白这个定义。 它只是将__off_t or _off64_t
定义为off_t
。 在哪里寻找__off_t
? 也是约定, __
是头文件中的大部分事物的前缀,当我阅读头文件以更好地理解时,会吓到我。 如何更好地读取头文件?
#ifndef __off_t_defined # ifndef __USE_FILE_OFFSET64 typedef __off_t off_t; # else typedef __off64_t off_t; # endif # define __off_t_defined #endif
由于这个答案仍然被投票,我想指出,你几乎不需要看头文件。 如果你想编写可靠的代码,通过查看标准,你会更好地服务。 比“在我的机器上如何定义off_t
”更好的问题是“标准怎么定义off_t
?”。 遵循标准意味着您的代码将在今天和明天在任何机器上运行。
在这种情况下, off_t
不是由C标准定义的。 这是POSIX标准的一部分, 您可以在这里浏览 。
不幸的是, off_t
没有被严格定义。 所有我能find的定义它是在sys/types.h
的页面上:
blkcnt_t
和off_t
应该是有符号整数types。
这意味着你不能确定它有多大。 如果您使用的是GNU C,则可以使用下面答案中的说明来确保它是64位。 或者更好的是,您可以在将其放置在电线上之前将其转换为标准定义的尺寸。 这就是Google的Protocol Buffers这样的项目(尽pipe这是一个C ++项目)。
所以,我认为“我在哪里可以find我的头文件中的定义”不是最好的问题。 但是,为了完整性,答案是:
你可以在bits/types.h
find这个定义(就像上面的注释一样,不要直接包含这个文件),但是在一堆macros中它会被遮住一点。 试图解开它们的另一种方法是查看预处理器输出:
#include <stdio.h> #include <sys/types.h> int main(void) { off_t blah; return 0; }
接着:
$ gcc -E sizes.c | grep __off_t typedef long int __off_t; ....
但是,如果您想知道某个东西的大小,则可以始终使用sizeof()
运算符。
编辑:刚才看到你的关于__
的问题的一部分。 这个答案有一个很好的讨论 。 关键是,以__
开头的名字是为实现保留的(所以你不应该用__
开始你自己的定义)。
正如“GNU C库参考手册”所说
off_t This is a signed integer type used to represent file sizes. In the GNU C Library, this type is no narrower than int. If the source is compiled with _FILE_OFFSET_BITS == 64 this type is transparently replaced by off64_t.
和
off64_t This type is used similar to off_t. The difference is that even on 32 bit machines, where the off_t type would have 32 bits, off64_t has 64 bits and so is able to address files up to 2^63 bytes in length. When compiling with _FILE_OFFSET_BITS == 64 this type is available under the name off_t.
因此,如果您想要在客户端和服务器之间表示文件大小的可靠方法,您可以:
- 相应地使用
off64_t
types和stat64()
函数(因为它填充结构stat64
,其中包含off64_t
types本身)。 键入off64_t
在32位和64位计算机上保证相同的大小。 - 如前所述,使用
-D_FILE_OFFSET_BITS == 64
编译代码 ,并使用通常的off_t
和stat()
。 -
将
off_t
转换为固定大小(C99标准)的int64_t
types。 注意:(我的书“坚果壳中的C”说它是C99标准,但在实现中是可选的)。 最新的C11标准说:7.20.1.1 Exact-width integer types 1 The typedef name intN_t designates a signed integer type with width N , no padding bits, and a two's complement representation. Thus, int8_t denotes such a signed integer type with a width of exactly 8 bits. without mentioning.
而关于实施:
7.20 Integer types <stdint.h> ... An implementation shall provide those types described as ''required'', but need not provide any of the others (described as ''optional''). ... The following types are required: int_least8_t uint_least8_t int_least16_t uint_least16_t int_least32_t uint_least32_t int_least64_t uint_least64_t All other types of this form are optional.
因此,一般来说,C标准不能保证具有固定大小的types。 但是大多数编译器(包括gcc)都支持这个function。
如果你正在编写可移植的代码,答案是“你不能说”,好消息是你不需要。 你的协议应该包括写大小为(例如)“8个八比特组,大端格式”(理想情况下,检查实际大小是否适合8个八位字节)。
如果在追踪定义时遇到问题,可以使用编译器的预处理输出,它会告诉你所有你需要知道的信息。 例如
$ cat test.c #include <stdio.h> $ cc -E test.c | grep off_t typedef long int __off_t; typedef __off64_t __loff_t; __off_t __pos; __off_t _old_offset; typedef __off_t off_t; extern int fseeko (FILE *__stream, __off_t __off, int __whence); extern __off_t ftello (FILE *__stream) ;
如果您查看完整的输出,甚至可以看到确切的头文件位置和行号:
# 132 "/usr/include/bits/types.h" 2 3 4 typedef unsigned long int __dev_t; typedef unsigned int __uid_t; typedef unsigned int __gid_t; typedef unsigned long int __ino_t; typedef unsigned long int __ino64_t; typedef unsigned int __mode_t; typedef unsigned long int __nlink_t; typedef long int __off_t; typedef long int __off64_t;
…
# 91 "/usr/include/stdio.h" 3 4 typedef __off_t off_t;