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_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;
}
_
その後:
_$ 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
_タイプとstat64()
関数を使用します(構造体_stat64
_を埋めるので、_off64_t
_タイプ自体が含まれます)。タイプ_off64_t
_は、32ビットマシンと64ビットマシンで同じサイズを保証します。-D_FILE_OFFSET_BITS == 64
_で通常の_off_t
_とstat()
を使用します。_off_t
_を固定サイズのタイプ_int64_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.
_
実装について:
_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;
移植可能なコードを書いている場合、答えは「わかりません」です。良いニュースは、あなたがする必要がないということです。プロトコルには、サイズを(たとえば)「8オクテット、ビッグエンディアン形式」として書き込む必要があります(理想的には、実際のサイズが8オクテットに収まることを確認します)。