Byte precision pointer arithmetic in C when sizeof(char) != 1

前端 未结 7 1259
悲哀的现实
悲哀的现实 2020-12-11 13:07

How can one portably perform pointer arithmetic with single byte precision?

Keep in mind that:

  • char is not 1 byte on all platforms
相关标签:
7条回答
  • 2020-12-11 13:09

    Your assumption is flawed - sizeof(char) is defined to be 1 everywhere.

    From the C99 standard (TC3), in section 6.5.3.4 ("The sizeof operator"):

    (paragraph 2)

    The sizeof operator yields the size (in bytes) of its operand, which may be an expression or the parenthesized name of a type.

    (paragraph 3)

    When applied to an operand that has type char, unsigned char, or signed char, (or a qualified version thereof) the result is 1.

    When these are taken together, it becomes clear that in C, whatever size a char is, that size is a "byte" (even if that's more than 8 bits, on some given platform).

    A char is therefore the smallest addressable type. If you need to address in units smaller than a char, your only choice is to read a char at a time and use bitwise operators to mask out the parts of the char that you want.

    0 讨论(0)
  • 2020-12-11 13:11

    According to the standard char is the smallest addressable chunk of data. You just can't address with greater precision - you would need to do packing/unpacking manually.

    0 讨论(0)
  • 2020-12-11 13:11

    I don't understand what you are trying to say with sizeof(void) being 1 in GCC. While type char might theoretically consist of more than 1 underlying machine byte, in C language sizeof(char) is 1 and always exactly 1. In other words, from the point of view of C language, char is always 1 "byte" (C-byte, not machine byte). Once you understand that, you'd also understand that sizeof(void) being 1 in GCC does not help you in any way. In GCC the pointer arithmetic on void * pointers works in exactly the same way as pointer arithmetic on char * pointers, which means that if on some platform char * doesn't work for you, then void * won't work for you either.

    If on some platform char objects consist of multiple machine bytes, the only way to access smaller units of memory than a full char object would be to use bitwise operations to "extract" and "modify" the required portions of a complete char object. C language offers no way to directly address anything smaller than char. Once again char is always a C-byte.

    0 讨论(0)
  • 2020-12-11 13:13

    sizeof(char) is guaranteed to be 1 by the C standard. Even if char uses 9 bits or more.

    So you can do:

    type *pt;
    unsigned char *pc = (unsigned char *)pt;
    

    And use pc for arithmetic. Assigning pc to pt by using the cast above is undefined behavior by the C standard though.

    If char is more than 8-bits wide, you can't do byte-precision pointer arithmetic in portable (ANSI/ISO) C. Here, by byte, I mean 8 bits. This is because the fundamental type itself is bigger than 8 bits.

    0 讨论(0)
  • 2020-12-11 13:19

    sizeof(char) always returns 1, in both C and C++. A char is always one byte long.

    0 讨论(0)
  • 2020-12-11 13:25

    The C99 standard defines the uint8_t that is one byte long. If the compiler doesn't support this type, you could define it using a typedef. Of course you would need a different definition, depending on the the platform and/or compiler. Bundle everything in a header file and use it everywhere.

    0 讨论(0)
提交回复
热议问题