[HN Gopher] Comp.lang.c Frequently Asked Questions
       ___________________________________________________________________
        
       Comp.lang.c Frequently Asked Questions
        
       Author : hliyan
       Score  : 85 points
       Date   : 2021-09-12 16:20 UTC (6 hours ago)
        
 (HTM) web link (c-faq.com)
 (TXT) w3m dump (c-faq.com)
        
       | hulitu wrote:
       | Also worth reading is C infrequently asked questions
       | https://www.seebs.net/faqs/c-iaq.html
        
         | BenjiWiebe wrote:
         | 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.
        
           | ziml77 wrote:
           | It may be based in truth, but it's a humor piece.
        
         | andi999 wrote:
         | For entertainment? Tone seems a bit over the top sarcastic.
        
           | gallier2 wrote:
           | If it is only the tone that bothers you, maybe you should
           | abstain from programming C. ;-)
        
             | andi999 wrote:
             | First tone then content...
        
       | thayne wrote:
       | > 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.
        
         | MaxBarraclough wrote:
         | Link to source of quote: http://c-faq.com/decl/exactsizes.html
         | 
         | 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.
        
         | addaon wrote:
         | 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.
        
       | k__ wrote:
       | Nice list, but would be cooler if it was scrollable. One question
       | per page is a bit tedious.
        
       | SavantIdiot wrote:
       | 1.1. How should I decide which integer type to use?
       | 
       | 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 wrote:
         | 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.
        
           | WalterBright wrote:
           | Use size_t to declare anything that will be used as an index.
        
             | SavantIdiot wrote:
             | This is literally the reason `size_t` was created.
        
               | jstanley wrote:
               | Why isn't it called index_t then?
        
               | SAI_Peregrinus wrote:
               | Because C doesn't really have indexes, it has pointers
               | and offsets. offset_t would make more sense than index_t.
        
               | burnished wrote:
               | As a fellow student of "why is this named that, what does
               | this name mean" I have found that asking about
               | counterfactuals is rarely satisfying. Naming stuff is
               | hard and the question assumed a level of intent that I
               | think is rarely present. Asking "how did this thing get
               | named that" works out better, cause it seems that
               | occasionally gets written down.
        
               | jstanley wrote:
               | My point was that it seems more likely that size_t was
               | created to represent sizes than to represent indexes.
               | 
               | I don't disagree that size_t is an appropriate type _for_
               | indexes, but I don 't think indexes are literally the
               | reason it was created.
        
               | tialaramex wrote:
               | It's named for sizeof, a C operator which returns a
               | positive integer but annoyingly the core C language
               | itself doesn't define what the type of that integer is,
               | the standard library does though, naming it size_t
               | 
               | Now, sizeof does measure the size of things, but, one of
               | the obvious sizes you can measure is an array+, and
               | that's definitely also the maximum index value for the
               | array, so I do think it's fair to say that's (part of)
               | literally why size_t exists.
               | 
               | + One of C's treacherous footguns. In the scope where the
               | array was defined it's an array, and sizeof(array) tells
               | you how big that array is. But, passed as a parameter it
               | becomes a _pointer_ and sizeof(resulting_pointer) is the
               | size of the pointer, not the array :(
        
         | saagarjha wrote:
         | Modern compilers generally prefer register-sized data.
        
           | SavantIdiot wrote:
           | Ah thanks, that's what I was thinking. But somehow I got
           | caught up in unaligned cacheline accesses, which are much
           | larger than 32-bits. It's early where I am. :)
        
             | masklinn wrote:
             | I mean there are 4 different concepts at play here:
             | 
             | Unaligned memory access, types generally have an alignment
             | which is the same as their length and structs have the
             | alignment of their largest member because many
             | architectures get quite cross with unaligned access e.g.
             | trying to load a 32b integer from memory to register while
             | it's not aligned to 32b, this is where compilers will pad
             | structures to ensure everything is aligned properly by
             | default, and where (in C/C++ anyway) you want to take care
             | of your struct layout to avoid unnecessary padding. That
             | doesn't prevent "these three should be shorts and these 10
             | can fit in chars." at all, but if you intersperse them the
             | structure will increase in size due to padding.
             | 
             | Then there's C being specified in terms of lowest
             | capabilities so while "char" and "short" are at least 8 and
             | at least 16 bits... they can also be larger (POSIX does
             | specify that char must be exactly 8 bits but non-POSIX
             | platforms don't require that). That matches everything
             | being 32b. It's a somewhat common occurrences for DSPs to
             | have char of 16 or 32 bits, it really has nothing to do
             | with the compiler (except insofar as the compiler does what
             | the architecture description specifies).
             | 
             | Then there's the preferred data size, which is probably a
             | function of the architectural ALUs than the native
             | registers e.g. if an architecture only works on 32b datum
             | then computations on 8 bit data will require loading 8
             | bits, zeroing the upper 24, performing the computation in
             | 32b, copying whichever bit is concerned to the overflow
             | flag, then zeroing that. Whereas performing the computation
             | on a 32b-native type would require loading 32b, performing
             | the computation, done (that was never a concern on x86/64
             | but IIRC older revisions of ARM could only natively work in
             | 32b, and not all possible arithmetic operations got
             | expanded to 8/16b at the same time).
             | 
             | And finally there's the cache line alignment. There are
             | actually two opposite issues with cacheline alignments: you
             | usually want your structure to not span cachelines (as that
             | gets more expensive) but sometimes you want your structures
             | be always start at the start of a cacheline (and possibly
             | take the entirety of the cacheline) to avoid _false
             | sharing_ issues: if two unrelated structures are on the
             | same cache line and they 're used from different cores, the
             | cores will need a lot more synchronisation than if they
             | were on different cache lines.
        
       | logbiscuitswave wrote:
       | 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.
        
         | Someone wrote:
         | http://c-faq.com/versions.html has downloads for ascii versions
         | (that may or may be up to date)
         | 
         | 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)
        
       | eps wrote:
       | Ooooh, this one's good - http://c-faq.com/struct/retcrash.html
        
         | buescher wrote:
         | I think I've done that one.
        
       | Doctor_Fegg wrote:
       | Newsgroup FAQs are a goldmine. I still find myself referring to
       | the comp.graphics.algorithms FAQ repeatedly:
       | 
       | http://www.faqs.org/faqs/graphics/algorithms-faq/
        
         | teddyh wrote:
         | Does anyone know what happened to rtfm.mit.edu? It was, quite
         | recently, an FTP site where all the Usenet FAQs were archived.
        
       | notorandit wrote:
       | Last update in 2005.
        
       | jftuga wrote:
       | I love this one:
       | 
       | Why do some people write if(0 == x) instead of if(x == 0)?
       | 
       | http://c-faq.com/style/revtest.html
        
       | bitwize wrote:
       | Written by my former colleague Steve Summit, probably the most
       | knowledgeable person this side of Dennis Ritchie about
       | programming C, especially in Unix environments.
        
         | kdavis wrote:
         | A giant among men ;)
        
       ___________________________________________________________________
       (page generated 2021-09-12 23:00 UTC)