Search code examples
ccross-platformfwritefread

Cross platform (de)serialization of char* from file


I need to fwritea char * to file and fread it on another platform where char's signedness varies.

  • Are there ways to solve this other than explicitly serializing a unsigned char*?
  • Is it always safe to cast a char* to an unsigned char*?

Solution

  • In C, it's safe to access any type as unsigned char [sizeof T]; this is called the representation. The question is whether copying this representation between diverse systems will preserve the value. Here are the relevant facts/issues:

    • All positive values of char (and keep in mind, all characters in the basic execution character set must be positive) have the same representation as an unsigned char with the same value. (The same applies to other signed/unsigned integer types too.)
    • On a twos-complement system, signed and unsigned char types are completely compatible (modulo the difference in how the values are interpreted) and it's perfectly safe to access them as either type. Moreover, the C standard makes it difficult if not impossible to produce a valid implementation where plain char is signed and not twos-complement, and I think it's safe to say no such implementation exists or will ever exist.
    • Even if the values as char (these are integers!) are preserved when transporting the file to another system, that doesn't necessarily imply that the character identities will be preserved, since the target system might use a different character encoding (EBCDIC puke..).

    This is a lot of mumbo-jumbo, but the result you should take away is that unless your goal is pedantry and language-lawyering, there's nothing to worry about. Just use fwrite and fread directly on strings and don't worry about whether they were unsigned char[] or char[] strings.