And then you get to the unfortunate situation that is the x64 ABIs - int is still 32-bit, leading to a bunch of extra movsx instructions if you use ints for things like indexing.
Worth noting that parts of it are trying to be funny, parts of it are plain wrong, and parts of it are dangerously misleading. There may be one or two useful bits in it somewheres too.
Written by my former colleague Steve Summit, probably the most knowledgeable person this side of Dennis Ritchie about programming C, especially in Unix environments.
While I don’t particularly like the structure of the FAQ (one page per item is definitely tedious to read through - I wish it came in a PDF or scrollable form) this is a goldmine of succinct and zero frills information. I learned a few things.
http://www.faqs.org/faqs/C-faq/faq/ has an ascii version from July 3, 2004 (again, I wouldn’t know whether that is up to date, but given its age, it may not be)
> Most programs do not need precise control over these sizes; many programs that do try to achieve this control would be better off if they didn't.
Interesting that modern languages like rust, go, and zig all lean towards using integer types with well defined sizes. I think that we've learned that the less exact definitions in c can cause problems. For example, if you develope and test in an environment where int is 32 bits, you could easily end up with bugs that only exist if int is 16 bits.
Modern C (from C99 onward) introduces a few families of sized types -- [u]int[_least|_fast|][8|16|32|64]_t. The non-least-or-fast types are not guaranteed to exist (e.g., int8_t is optional because implementation may be unreasonable on a 24-bit DSP with no sub-word operations), but the _least and _fast types are generally what you want anyway, unless you're relying on unsigned overflow behavior.
In my experience, modern code is either written almost entirely in terms of sized values like int32_t (when assuming a "normal" platform), or almost entirely in terms of _least/_fast values (when going for maximum portability). The only case that "naked" int/long is still common in this model is in a few specific uses such as loop indices where it's idiomatic.
The _fast and _least types are especially interesting, pragmatically. "int_fast8_t" means "I need a signed value that can store values between -128 and 127, doesn't have defined behavior on overflow, and is allowed to fill a register / use a word worth of memory." "int_least8_t" means "I need a signed value that can store values between -128 and 127, doesn't have defined behavior on overflow, and I am likely to have a significant number of these in memory so please pack them as efficiently as reasonable." (And of course we have bit packing when we need to pack more efficiently than reasonable; bit-packing with int_fast8_t allows you to represent "I need this to take exactly 8 bits of memory, whatever it costs compute-wise, because I'm basically filling memory with these.")
In general, I find that these types give modern C a good balance between declaring requirements on types and not overly trying to control their size.
I'm fond of Ada's approach: generally you just specify the range you want and let the compiler figure out the best integer size to use. You only need to specify a size if you're doing low-level work or FFI.
Technically the wrong type was used if no less than 32 bits was desired. A common failing when you learn a compiler/platform or two instead of the language. Such has been called many things, among them 'everything is a VAX'.
I often cite section 6. It's the best explanation I've found of the (often confusing and counterintuitive) relationship between arrays and pointers in C.
If you think arrays are really pointers, you need to read section 6 of the FAQ.
[+] [-] Doctor_Fegg|4 years ago|reply
http://www.faqs.org/faqs/graphics/algorithms-faq/
[+] [-] teddyh|4 years ago|reply
[+] [-] SavantIdiot|4 years ago|reply
Programmer: Hmmm, I think these three should be shorts and these 10 can fit in chars.
Modern compiler: Fuck that, you're all 32-bits. I ain't got time for unaligned memory access...
[+] [-] sdfdf4434r34r|4 years ago|reply
[+] [-] saagarjha|4 years ago|reply
[+] [-] hulitu|4 years ago|reply
[+] [-] BenjiWiebe|4 years ago|reply
[+] [-] andi999|4 years ago|reply
[+] [-] bitwize|4 years ago|reply
[+] [-] kdavis|4 years ago|reply
[+] [-] eps|4 years ago|reply
[+] [-] buescher|4 years ago|reply
[+] [-] logbiscuitswave|4 years ago|reply
[+] [-] Someone|4 years ago|reply
http://www.faqs.org/faqs/C-faq/faq/ has an ascii version from July 3, 2004 (again, I wouldn’t know whether that is up to date, but given its age, it may not be)
[+] [-] thayne|4 years ago|reply
Interesting that modern languages like rust, go, and zig all lean towards using integer types with well defined sizes. I think that we've learned that the less exact definitions in c can cause problems. For example, if you develope and test in an environment where int is 32 bits, you could easily end up with bugs that only exist if int is 16 bits.
[+] [-] addaon|4 years ago|reply
In my experience, modern code is either written almost entirely in terms of sized values like int32_t (when assuming a "normal" platform), or almost entirely in terms of _least/_fast values (when going for maximum portability). The only case that "naked" int/long is still common in this model is in a few specific uses such as loop indices where it's idiomatic.
The _fast and _least types are especially interesting, pragmatically. "int_fast8_t" means "I need a signed value that can store values between -128 and 127, doesn't have defined behavior on overflow, and is allowed to fill a register / use a word worth of memory." "int_least8_t" means "I need a signed value that can store values between -128 and 127, doesn't have defined behavior on overflow, and I am likely to have a significant number of these in memory so please pack them as efficiently as reasonable." (And of course we have bit packing when we need to pack more efficiently than reasonable; bit-packing with int_fast8_t allows you to represent "I need this to take exactly 8 bits of memory, whatever it costs compute-wise, because I'm basically filling memory with these.")
In general, I find that these types give modern C a good balance between declaring requirements on types and not overly trying to control their size.
[+] [-] MaxBarraclough|4 years ago|reply
I'm fond of Ada's approach: generally you just specify the range you want and let the compiler figure out the best integer size to use. You only need to specify a size if you're doing low-level work or FFI.
[+] [-] Hfdlmsh|4 years ago|reply
[+] [-] k__|4 years ago|reply
[+] [-] _kst_|4 years ago|reply
If you think arrays are really pointers, you need to read section 6 of the FAQ.
[+] [-] jftuga|4 years ago|reply
Why do some people write if(0 == x) instead of if(x == 0)?
http://c-faq.com/style/revtest.html
[+] [-] qweqwweqwe-90i|4 years ago|reply
[+] [-] sanj|4 years ago|reply
[+] [-] notorandit|4 years ago|reply