25

Does it make a difference which one I use in objective-c (particularly on iOS)? I assume it comes from inheriting from C and its types, as well as inheriting the types from Mac OS, which iOS was based on, but I don't know which one I should use:

unsigned char from...well..the compiler?

uint8_t from stdint.h

UInt8 from MacTypes.h

Byte from MacTypes.h

Bytef from zconf.h

I am aware that the various defs are for portability reasons, and using literals like unsigned char is not good future thinking (size might change, and things will end up like the Windows API again). I'd like some advice on how to spot the best ones for my uses. Or a good tongue lashing if I'm just being silly...

EDIT : Just for some more info, if I want something that will always be 1 byte, should I use uint8_t (doesn't seem like it would change with a name like that)? I'd like to think UInt8 wouldn't change either but I see that the definition of UInt32 varies on whether or not the processor is 64-bit.

FURTHER EDIT : When I say byte, I specifically mean that I want 8 bits. I am doing pixel compression operations (32 bits -> 8 bits) for disk storage.

Alexander Abakumov
  • 13,617
  • 16
  • 88
  • 129
borrrden
  • 33,256
  • 8
  • 74
  • 109
  • 2
    This may help: http://stackoverflow.com/questions/1725855/uint8-t-vs-unsigned-char – Adam Jun 08 '12 at 09:21

2 Answers2

11

It's totally indifferent. Whichever you use, it will most probably end up being an unsigned char. If you want it to look nice, though, I suggest you use uint8_t from <stdint.h>.

Neither will change with the architecture. char is always 1 byte as per the C standard, and it would be insupportable from a user's point of view if in an implementation, UInt8 suddenly became 16 bits long.

(It is not the case, however, that char is required to be 8 bits wide, it's only that if the name of a type suggest that it's 8 bits long, then any sensible implementation does indeed typedefs it as such. Incidentally, a byte (which char is) is often an 8-bit unit, i. e. an octet.)

  • 1
    @borrrden `uint8_t ` should never change, or the name would be just totally wrong. I think that wouldn't be a bad choise. It shows your intention of using an unsigned byte variable. – kratenko Jun 08 '12 at 09:22
  • A potential nasty gotcha is that nothing would forbid an implementation from defining an 8-bit "extended integer type" and defining uint8_t as an alias to that. Although an implementation given `uint16_t x=0xFFFF;` would be required to make `uint8_t y=*((unsigned char *)&x);` yield 255, no such requirement would apply if the expression was written `*((uint8_t*)&x)` and `uint8_t` was considered a "non-character" type. – supercat Aug 15 '16 at 18:21
  • Right. `sizeof(char) == 1` but the standard does not require the units of `sizeof` to be 8-bit bytes (aka "octets"). – Brian White Jul 27 '17 at 19:19
1

As in every programming language derived from C-language type model, Objective C has a handful of equivalent options to declare a 8-bit integer.

Why did I say equivalent? Because as OP correctly stated, it's obvious that all of those options eventually typedef-ed to unsigned char built-in compiler type. This is correct for now and, let's speak practically, nobody sane will change them to be a non-8-bit integers in the future.

So, the actual question here is what is the better order to prioritize considerations when choosing the type name for 8-bit integer?

Code readability

Since basically in every code having C language roots, primitive type names are a mess. Therefore, probably the most important factor is readability. And by that I mean clear and uniquely identifiable intent of choosing this specific type for this specific integer for the majority of people who would read your code.

So let's take look at those types from an average Objective C programmer point of view who knows little about C language.

  • unsigned char - what's this??? why char is ever meant to be signed???
  • uint8_t - ok, unsigned 8 bit integer
  • UInt8 - hmm, the same as above
  • Byte - signed or unsigned 8 bit integer
  • Bytef - what's this? byte-float? what does that 'f' mean?

It's obvious here that unsigned char and Bytef aren't a good choices.

Going further, you can notice another nuisance with Byte type name: you can't say for sure if it represents signed or unsigned integer which could be extremely important when you're trying to understand what is the range of values this integer could hold (-128 .. 127 or 0 .. 256). This is not adding points to code readability, too.

Uniform code style

We're now left with the 2 type names: uint8_t and UInt8. How to choose between them?

Again, looking at them through the eyes of an Objective C programmer, who is using type names like NSInteger, NSUInteger a lot, it looks like much natural when he sees UInt8. uint8_t just looks like a very low-level daunting stuff.

Conclusion

Thus, we eventually are left with the single option - UInt8. Which is clearly identifiable in terms of number of bits, range and looks accustomed. So it's probably the best choice here.

Alexander Abakumov
  • 13,617
  • 16
  • 88
  • 129