Path: csiph.com!news.mixmin.net!eternal-september.org!reader01.eternal-september.org!.POSTED!not-for-mail From: Tim Rentsch Newsgroups: comp.lang.c Subject: Re: Beginner....Decimal/Octal converter help Date: Wed, 14 Sep 2022 03:24:08 -0700 Organization: A noiseless patient Spider Lines: 89 Message-ID: <867d26ntiv.fsf@linuxsc.com> References: <8ffd982c-2e82-4caa-9256-ec17be2efe56n@googlegroups.com> <86leqsr091.fsf@linuxsc.com> <875yhv30nu.fsf@bsb.me.uk> <87zgf714zc.fsf@bsb.me.uk> <8735cy0wt4.fsf@bsb.me.uk> <87r10hzn19.fsf@bsb.me.uk> <86v8ptpa7u.fsf@linuxsc.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Injection-Info: reader01.eternal-september.org; posting-host="e4a07c6eb40a7dcf36ed28254bbf399a"; logging-data="3046766"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX1/tQM9PoWJJtYpGjVLsoYb5YB2aRLd2YWI=" User-Agent: Gnus/5.11 (Gnus v5.11) Emacs/22.4 (gnu/linux) Cancel-Lock: sha1:nLHS5V1R5uE9DildSp/z7huI4XQ= sha1:kcTNroR6evdPEgbrjtgg9NVhzGE= Xref: csiph.com comp.lang.c:167704 Richard Damon writes: > On 9/11/22 11:01 PM, Tim Rentsch wrote: > >> Ben Bacarisse writes: >> >>> [...] I worry that, except when matching externally defined >>> structures, the use of the intN_t (and maybe even the uintN_t) >>> types is almost always knee-jerk programming. >> >> Completely agree. > > I would just slightly disagree. > > Many programs are not designed to be "highly portable", and it may be > a reasonable assumption that a given program will only be run on > machines which is based on 8 bit bytes. I am taking 8-bit bytes as being the crucial property in the remarks below. There are obvious counterparts for other properties, such as having a two's complement representation. > Since [u]intN_t is the shortest way to specify a size that will likely > migrate over modereate architecture variations for variable where you > do want to specify the "size" of the variable, using them makes sense. First off, I wouldn't say using int8_t or uint8_t is the shortest way to ensure 8-bit bytes. The way such types are typically used, there will be lots of 'int8_t's or 'uint8_t's scattered through the source code, with a correspondingly large footprint in the program source. It is shorter to write in just one header file in the program #include #if CHAR_BIT != 8 # error oops.. this program relies on chars being 8 bits... #endif typedef unsigned char U8; typedef signed char S8; which also can be used in implementations that don't support C99. Second, ignoring the question of which technique is shortest, using [u]int8_t is often not a good way. A problem with the exact width types is that they are both an under-specification and an over-specification: over-specification because they often include properties that aren't important (such as having no trap representations), and under-specification because they might not have properties that are otherwise desirable (such as being exempt from anti-alias rules, as the character types are). Granted, such problems are not likely to occur, but there is no good reason to take the risk when it can be easily avoided. Third, using exact width types can have consequences for parts of the code other than declarations. In effect using exact width types in one part of a program pushes the program into a mode where exact width types more or less have to be used everywhere, even when they are needed in only a few places. Even if exact width types are an acceptable choice, in most cases they are not the best choice. In summary, I think a better statement is that [u]intN_t is the laziest way to achieve what may not be a good result, and often is a suboptimal result. The sad thing is that better techniques don't need a lot of overhead; there is a small upfront cost, but once that initial cost has been paid the incremental cost is basically zero. > Perhaps instead of making the type least_intN_t/fast_intN_t/intN_t > they were defined instead as intN_t/fast_intN_t/exact_intN_t, or > least_intN_t/intN_t/exact_intN_t so the simple name was one of the > promised to exist types that might be bigger if needed, the short name > bias would have lead to better code, but that ship has sailed. Something that hasn't come up (I think) in the discussion of various type choices is the distinction between types and the names of types. In the code that I posted, the types used are unsigned char and unsigned int. To help the discussion I put in some typedefs to give the names UC and UI to these types, but that doesn't change what the underlying types are. One problem with the types in is we don't know whether these names refer to existing (standard) types, or whether they refer to non-standard extended types. Are they fish or fowl? We don't know. That uncertainty can cause difficulties in code that uses some types. For the most part I usually avoid using any types, for this reason and also for the reasons explained above.