Programming C, C++, Java, PHP, Ruby, Turing, VB
Computer Science Canada 
Programming C, C++, Java, PHP, Ruby, Turing, VB  

Username:   Password: 
 RegisterRegister   
 Help understanding this File I/O Example
Index -> Programming, C++ -> C++ Help
View previous topic Printable versionDownload TopicSubscribe to this topicPrivate MessagesRefresh page View next topic
Author Message
copthesaint




PostPosted: Mon Feb 11, 2013 2:27 pm   Post subject: Help understanding this File I/O Example

I was reading an example online for File I/O, here is the link for the Source.

I have a few questions that I hope can be better explained.

1: Is the friend function in this example ever used? I can't see that there is any direct use of it in this function. Is it purely exemplary?

2: When fstream writes the binary information for the class, what is written? I would have to guess when the class is written, so is the information for the size of the objects in the class, 4 bytes for the int, 1 byte for the char but what is the other 3 bytes for? (assuming what is written is derived from the size of the class.)

Thanks if you help provide any clarity.
Sponsor
Sponsor
Sponsor
sponsor
DemonWasp




PostPosted: Mon Feb 11, 2013 7:18 pm   Post subject: RE:Help understanding this File I/O Example

The friend qualifier on a function just says "this function can access private members", even though technically that function, operator<<(ostream&, const ExampleClass&) isn't technically a member function of either ostream or ExampleClass.

Because it's an operator overload, it gets called by this line:
code:
cout << c << endl;


Yes, that is confusing. No, it's not about to get any better.

By (2), I'm going to assume you mean this bit:
code:

void write_binary_output_example()
{
    // ...

    ExampleClass c('C', 3);

    // ...

    // This line, here:
    file.write((char *)(&c), sizeof(c));
}


What that actually writes out is...surprisingly complicated. Your C++ compiler is free to rearrange the members of your class in memory in any way it damn well pleases. This is required because C++ is supposed to work "across platforms", and some platforms require specific alignments for memory access. For speed, it's also generally preferable to align things in a particular way. On the most common x86 and x64 systems, alignments of 4 and 8 bytes are ideal. For a full discussion, see: http://en.wikipedia.org/wiki/Data_structure_alignment

Long story short, that line:
- means something that is inherently compiler-specific, target architecture-specific, and sensitive to compilation flags and #pragma(pack), among other things
- doesn't mean the same thing from one computer to the next, from one compiler to the next, across a network, or even between operating systems on the same computer, with the same compiler
- doesn't necessarily output data in the order you want

In general, though, it will just write the contents of the member variables in the class definition. For pointer members, it will write the address of the pointer rather than dereferencing it and printing its contents. I imagine that references would behave similar to pointers, but I'm not on Linux right now, so I'm not going to test it.

For example if I print an instance of a class that looks like this (given those assignments):
code:

class Example {
private:
   int a = 3;
   char b = 'b';
   string s = "example";
};


Then the output would contain an integer that represents "3" (either big-endian or little-endian, depending on the machine; probably 4 bytes on an x86 computer, but potentially any other number of bits or bytes); a character that represents 'b' (probably a single byte, in ASCII, with value 98 = 0x62; but potentially encoded in EBCDIC or any other single-byte encoding; potentially, it could even be more or less than a byte, if the target computer even uses bytes, which it may not).

The output would also contain the private members of the std::string implementation, which depend entirely on which implementation of the standard is used. I would assume that they would be string length, buffer size, and a pointer to the buffer, but they could easily be different.

The order of these can be shuffled. Although the contents of std::string won't have Example::a or Example::b mixed into them, they could be ordered [a;s;b], [a;b;s], [b;s;a] or any other shuffling. Plus, the contents of string itself may be in any order they want.

Assuming you're on an x86 system, then presumably the int is 4 bytes in little-endian order and the the char is in ASCII and is one byte. If we assume that std::string is packed [size;length;buffer*], and that compilation assumed 4-byte pointers, then std::string would probably consume 12 bytes (4 each for size, length, and buffer*).

If you forced the compiler to pack your structure in the order you gave (by compiler arguments or by #pragma's), then the resulting structure on disk would look like [a;b;___;s::size;s::length;s::buffer*] and would be 20 bytes long. The triple-underscore, ___, denotes three bytes of "padding" to make the fields in std::string be word-aligned. If it had the example contents above, then it would start with (hex, divided into bytes): 03 00 00 00 62 00 00 00 07 00 00 00 ?? ?? ?? ?? ?? ?? ?? ??

The last few question marks correspond to the length of the std::string buffer, which is selected by that particular implementation, and a pointer to the char* buffer, which is dependent on so many factors I can't even begin describing them here.

Worse, suppose that you tried to use this as a save-game format. If you read that structure off the disk, then the pointer used by std::string will almost certainly be invalid, and will therefore crash your program when you try to access its contents.

This is why binary formats are usually written out manually.
copthesaint




PostPosted: Wed Feb 13, 2013 3:10 am   Post subject: RE:Help understanding this File I/O Example

Couldn't ask for a better explanation, thanks!
Display posts from previous:   
   Index -> Programming, C++ -> C++ Help
View previous topic Tell A FriendPrintable versionDownload TopicSubscribe to this topicPrivate MessagesRefresh page View next topic

Page 1 of 1  [ 3 Posts ]
Jump to:   


Style:  
Search: