Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Should I trust that a short in C will be 2 bytes usually?

Tags:

c

int

short

I have a large number that loops from 0 to 65535 (I chose 16 bits simply to have a nice cutting off point). I'm incrementing an int, and there's an if statement that checks if the int is 65536. If it is, it sets the int to 0; a little kludgy, but it works. I know it would be much more efficient to just use a short int and let it overflow, but I initially didn't do that because a short is not guaranteed to be 2 bytes, it's just fairly likely.

This is C code running on a linux (ubuntu) machine. If I were to use a short and later decided to run this program on another OS (or say, run it on a 64-bit machine, since I'm testing on a 32-bit one now), is there a pretty good chance that my short will still be 2 bytes? I can easily test it on a few different machines, but some of the people here have worked with a LOT of computers. Is there a terrible pitfall I should be watching out for?

like image 313
cost Avatar asked Dec 01 '22 03:12

cost


2 Answers

There is no guarantee of the size of any of the built-in types like int, char and the like. (See for example this question, which is about C++, but is also accurate for C as far as I know in this regard)

If you need fixed-size integer types, include C99's <stdint.h> and use the fixed-width typesdefined there.

like image 173
rubenvb Avatar answered Dec 04 '22 21:12

rubenvb


Short is 16 bits on the vast majority of compilers. If at all reasonable, I'd probably use a bit-field for the job:

struct { 
    unsigned short my_number : 16;
};

In a typical case where short is 16 bits anyway, this won't impose any overhead -- and in the rare case that some extra code needs to be inserted to clamp the value to the right range, this handles that automatically.

The only shortcoming is that you can only have a bit-field inside a struct.

Edit: It's unfortunate that @earlz deleted his answer, because his idea was actually better than he thought: if a C99 implementation has a 16-bit unsigned integer type, it's required to provide uint16_t as a typedef for that type. If provided, this must be exactly 16 bits wide. There's also a uint_least16_t that fits his description (at least 16 bits wide, but could be more).

like image 30
Jerry Coffin Avatar answered Dec 04 '22 20:12

Jerry Coffin