IT Share you

off_t 유형의 완전한 정의는 어디에서 찾을 수 있습니까?

shareyou 2020. 11. 30. 20:16
반응형

off_t 유형의 완전한 정의는 어디에서 찾을 수 있습니까?


TCP를 사용하여 클라이언트에서 서버로 파일을 보내고 있습니다. 파일의 끝을 표시하기 위해 실제 데이터보다 먼저 파일 크기를 보내고 싶습니다. 그래서 stat시스템 호출을 사용 하여 파일의 크기를 찾습니다. 이것은 유형 off_t입니다. 서버 측에서 제대로 읽을 수 있도록 얼마나 많은 바이트를 차지하는지 알고 싶습니다. 그것은에 정의되어 있습니다 <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_tC 표준에 의해 정의되지 않습니다. POSIX 표준의 일부이며 여기에서 찾아 볼 수 있습니다 .

불행히도 off_t그다지 엄격하게 정의되지 않았습니다. 정의 할 수있는 것은 다음 페이지에 있습니다 sys/types.h.

blkcnt_toff_t유형 정수 서명해야한다.

이것은 그것이 얼마나 큰지 확신 할 수 없다는 것을 의미합니다. GNU C를 사용하는 경우 아래 답변 의 지침을 사용하여 64 비트인지 확인할 수 있습니다. 또는 와이어에 넣기 전에 표준 정의 크기로 변환 할 수 있습니다. 이것이 Google의 프로토콜 버퍼 와 같은 프로젝트가 작동하는 방식입니다 (C ++ 프로젝트 임에도 불구하고).


그래서 "내 헤더 파일에서 정의를 어디에서 찾을 수 있는가"가 최선의 질문이 아니라고 생각합니다. 그러나 완전성을 위해 여기에 답이 있습니다.

에서 정의를 찾을 수 있지만 bits/types.h(댓글이이 파일을 직접 포함하지 마십시오), 많은 매크로에서 약간 가려집니다. 이를 풀기위한 대안은 전 처리기 출력을 보는 것입니다.

#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.

따라서 클라이언트와 서버 간의 파일 크기를 안정적으로 표현하려면 다음을 수행 할 수 있습니다.

  1. 그에 따라 off64_t유형과 stat64()함수를 사용하십시오 ( 유형 자체 stat64를 포함하는 structure를 채울 때 off64_t). 유형 off64_t은 32 비트 및 64 비트 시스템에서 동일한 크기를 보장합니다.
  2. 전에 언급했듯이 코드컴파일 -D_FILE_OFFSET_BITS == 64하고 평소 off_tstat().
  3. 고정 크기 (C99 표준)의 off_t유형 int64_t으로 변환 합니다 . 참고 : (내 책 '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.
    

    그리고 구현에 대해 :

    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 표준은 크기가 고정 된 유형을 보장 할 수 없습니다. 그러나 대부분의 컴파일러 (gcc 포함)는이 기능을 지원합니다.


정의를 추적하는 데 문제가있는 경우 컴파일러의 전처리 된 출력을 사용하여 알아야 할 모든 것을 알 수 있습니다.

$ 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;

If you are writing portable code, the answer is "you can't tell", the good news is that you don't need to. Your protocol should involve writing the size as (eg) "8 octets, big-endian format" (Ideally with a check that the actual size fits in 8 octets.)

참고URL : https://stackoverflow.com/questions/9073667/where-to-find-the-complete-definition-of-off-t-type

반응형