コンピュータや音楽の事書いてます

FILE構造体とfstream

std::fstreamの中にFILE構造体をラッピングしてあると思ったので、ヘッダファイルを辿って調べてみた。

gcc 4.1.1

gccのlibio.h

struct _IO_FILE {
  int _flags;   /* High-order word is _IO_MAGIC; rest is flags. */
#define _IO_file_flags _flags

  /* The following pointers correspond to the C++ streambuf protocol. */
  /* Note:  Tk uses the _IO_read_ptr and _IO_read_end fields directly. */
  char* _IO_read_ptr; /* Current read pointer */
  char* _IO_read_end; /* End of get area. */
  char* _IO_read_base;  /* Start of putback+get area. */
  char* _IO_write_base; /* Start of put area. */
  char* _IO_write_ptr;  /* Current put pointer. */
  char* _IO_write_end;  /* End of put area. */
  char* _IO_buf_base; /* Start of reserve area. */
  char* _IO_buf_end;  /* End of reserve area. */
  /* The following fields are used to support backing up and undo. */
  char *_IO_save_base; /* Pointer to start of non-current get area. */
  char *_IO_backup_base;  /* Pointer to first valid character of backup area */
  char *_IO_save_end; /* Pointer to end of non-current get area. */

  struct _IO_marker *_markers;

  struct _IO_FILE *_chain;
/**********長いので省略*********/

gccのstdio.h

  typedef struct _IO_FILE FILE;

c++/4.1.1/x86_64-redhat-linux/bits/c++io.h

  typedef FILE __c_file;

c++/4.1.1/x86_64-redhat-linux/bits/basic_file.h

class __basic_file<char> {
__c_file*   _M_cfile;

fstream

class basic_filebuf : public basic_streambuf<_CharT, _Traits>{
public:
  typedef __basic_file<char>                __file_type;
protected:
  __file_type     _M_file;

さらにgccビルド前ソースの奥地まで調査に出かけた。
libstdc++-v3/config/io/basic_file_stdio.ccの中にfopen()発見!
さっき見つけた _M_cfile にfopenの結果を代入している。

  __basic_file<char>*
  __basic_file<char>::open(const char* __name, ios_base::openmode __mode, int /*__prot*/)
  {
    __basic_file* __ret = NULL;
    const char* __c_mode = fopen_mode(__mode);
    if (__c_mode && !this->is_open())
      {
#ifdef _GLIBCXX_USE_LFS
        if ((_M_cfile = fopen64(__name, __c_mode)))
#else
        if ((_M_cfile = fopen(__name, __c_mode)))
#endif
          {
            _M_cfile_created = true;
            __ret = this;
          }
      }
    return __ret;
  }

コンパイラ

コンパイラのstdio.h

struct _iobuf {
        char *_ptr;
        int   _cnt;
        char *_base;
        int   _flag;
        int   _file;
        int   _charbuf;
        int   _bufsiz;
        char *_tmpfname;
        };
typedef struct _iobuf FILE;

シンプル。

コンパイラのcstdio

 #define _Filet	FILE

コンパイラのfstream

extern _MRTIMP2_NCEEPURE _Filet *__CLRCALL_PURE_OR_CDECL _Fiopen(const char *,	ios_base::openmode, int);

template<class _Elem,	class _Traits>
	class basic_filebuf : public basic_streambuf<_Elem, _Traits>
	{	// stream buffer associated with a C stream
public:
/**********中略************/
	_Myt *__CLR_OR_THIS_CALL open(const char *_Filename, ios_base::openmode _Mode,
		int _Prot = (int)ios_base::_Openprot)
		{	// open a C stream with specified mode
		_Filet *_File;
		if (_Myfile != 0 || (_File = _Fiopen(_Filename, _Mode, _Prot)) == 0)
			return (0);	// open failed
/**********中略************/
  _Myfile = _File;
/**********中略************/
private:
  _Filet *_Myfile;	// pointer to C stream

fopenじゃなくて_Fiopenだけど、似たようなもんだろう。

感想

コンパイラの方がすっきりしてて分りやすい。