哪里可以找到off_t类型的完整定义?

Fou*_*ind 63 c sockets networking types header-files

我正在使用TCP将文件从客户端发送到服务器.为了标记文件的结尾,我想在实际数据之前发送文件大小.所以我使用stat系统调用来查找文件的大小.这是类型off_t.我想知道它占用了多少字节,以便我可以在服务器端正确读取它.它定义于 <sys/types.h>.但我不明白这个定义.它只是定义__off_t or _off64_toff_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 
Run Code Online (Sandbox Code Playgroud)

Tim*_*nes 77

由于这个答案仍然被投票,我想指出你几乎不需要查看头文件.如果您想编写可靠的代码,那么通过查看标准可以获得更好的服务.比" off_t我的机器上如何定义"更好的问题是" off_t标准如何定义?".遵循标准意味着您的代码将在今天和明天在任何机器上运行.

在这种情况下,off_t不是由C标准定义的.它是POSIX标准的一部分,您可以在这里浏览.

不幸的是,off_t没有非常严格的定义.我能找到的所有内容都在页面上sys/types.h:

blkcnt_t并且off_t应该是有符号整数类型.

这意味着你无法确定它有多大.如果您使用的是GNU C,则可以使用下面的答案中的说明来确保它是64位.或者更好的是,您可以在将其放入线路之前转换为标准定义的大小.这就是Google的Protocol Buffers等项目的工作方式(尽管这是一个C++项目).


所以,我认为"我在哪里可以找到头文件中的定义"并不是最好的问题.但是,为了完整性,这里是答案:

你会发现定义bits/types.h(如顶部的注释所示,从不直接包含这个文件),但它在一堆宏中有点模糊.尝试解开它们的另一种方法是查看预处理器输出:

#include <stdio.h>
#include <sys/types.h>

int main(void) {
  off_t blah;

  return 0;
}
Run Code Online (Sandbox Code Playgroud)

然后:

$ gcc -E sizes.c  | grep __off_t
typedef long int __off_t;
....
Run Code Online (Sandbox Code Playgroud)

但是,如果您想知道某些内容的大小,您可以随时使用该sizeof()运算符.

编辑:刚刚看到你的问题的一部分__.这个答案有很好的讨论.关键点是以开头的名称__为实现保留(所以你不应该开始自己的定义__).

  • 在两台机器上不能保证长长度相同 - 确切的尺寸不是标准化的. (4认同)

lik*_*ern 36

正如"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.
Run Code Online (Sandbox Code Playgroud)

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.
Run Code Online (Sandbox Code Playgroud)

因此,如果您想要在客户端和服务器之间表示文件大小的可靠方法,您可以:

  1. 相应地使用off64_t类型和stat64()函数(因为它填充结构stat64,其中包含off64_t类型本身).off64_t在32位和64位计算机上键入相同大小的保证.
  2. 正如前面所提到的编译代码-D_FILE_OFFSET_BITS == 64和使用通常的off_tstat().
  3. 转换off_tint64_t固定大小的类型(C99标准). 注意:(我的书"C in a Nutshell"表示它是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.
    
    Run Code Online (Sandbox Code Playgroud)

    关于实施:

    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.
    
    Run Code Online (Sandbox Code Playgroud)

因此,通常,C标准不能保证具有固定大小的类型.但大多数编译器(包括gcc)都支持此功能.


chu*_*utz 7

如果您在跟踪定义时遇到问题,可以使用编译器的预处理输出,它将告诉您需要知道的所有内容.例如

$ 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) ;
Run Code Online (Sandbox Code Playgroud)

如果查看完整输出,您甚至可以看到确切的头文件位置和定义它的行号:

# 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;
Run Code Online (Sandbox Code Playgroud)

...

# 91 "/usr/include/stdio.h" 3 4
typedef __off_t off_t;
Run Code Online (Sandbox Code Playgroud)


Mar*_*ica 5

如果您正在编写可移植的代码,则答案是“您无法分辨”,好消息是您不需要。您的协议应包括将大小写为“例如8个八位字节,大端格式”(最好检查一下实际大小是否适合8个八位字节。)