home bbs files messages ]

Forums before death by AOL, social media and spammers... "We can't have nice things"

   comp.lang.c      Meh, in C you gotta define EVERYTHING      243,242 messages   

[   << oldest   |   < older   |   list   |   newer >   |   newest >>   ]

   Message 242,188 of 243,242   
   bart to David Brown   
   Re: _BitInt(N)   
   27 Nov 25 17:13:50   
   
   From: bc@freeuk.com   
      
   On 27/11/2025 13:02, David Brown wrote:   
   > On 27/11/2025 13:20, bart wrote:   
      
   > In some areas of C usage, shifts and masks - and bitfield extraction -   
   > turn up quite a bit.  But it seems the C operators work fine for the   
   > task.  It would not exactly be difficult to add a standard   
   > "bit_range_extract" function to the C standard library, yet no one has   
   > felt it to be worth the effort over the last 50 years.   
      
   That doesn't say much. Binary literals only became official in C23.   
      
   Width-specific integers only became standard in C99 (what did people use   
   in the preceding quarter-century?) and are not yet in the core language.   
      
   Such things as bit-extraction don't get prioritised because it so easy   
   for people to put together some crummy macro to do the job. But this   
   means everybody will create their own incompatible solutions.   
      
   Min/Max operators, or 'lengthof', will never get added for similar   
   reasons. But there was a time when every other code-base I looked at   
   defined its own MIN/MAX or Min/Max or min/max macros or functions.   
      
   Examples:   
      
      #define MZ_MAX(a, b) (((a) > (b)) ? (a) : (b))  (MZ lib)   
      
      # define MAX(A,B) ((A)>(B)?(A):(B))             (SQLite)   
      
      #define MAX(a,b)	((a) > (b) ? (a) : (b))   (LIBjpeg)   
      
   While everywhere you see patterns like:   
      
      sizeof(somearray/somearray[0])   
      
   which is crying out for standardisation.   
      
   Here, I guess 'no one has felt it to be worth the effort'. Except me.   
      
      
   >> The syntax actually comes from DEC Algol60 IIRC. It was used to access   
   >> individual characters of a string, normally an indivisible type in   
   >> that language, and I applied the same concept to bits of an integer.   
   >   
   > I don't care if you found the syntax on the back of a cornflakes packet.   
   >   The origin is not relevant.   
      
   Oh, I thought it was an automatic negative reaction from you to anything   
   I'd thought up. I guess you have it in for DEC too.   
      
      
   >>   
   >>>> How much more fundamental can you get?   
   >>>   
   >>> It is not fundamental for a low-level systems language.   
   >>   
   >> So bits are not fundamental either! But then, it has taken until C23   
   >> to standardise binary literals, and there is still no format code for   
   >> binary output.   
   >>   
   >   
   > Very few programmers are at all interested in bits.   
      
   Unless it is that extra bit in _BitInt(65)! Then it is apparently vital.   
      
      A "double" holds a   
   > floating point value, not a pattern of bits.  You are thinking on a   
   > level of abstraction that is not realistic for most programming tasks.   
      
   This is systems programming.   
      
   >> They frequently have advanced features while ignoring the basics.   
   >   
   > No - they frequently have features that /you/ call "advanced" because   
   > you don't need or want them, and they ignore things that /you/ call   
   > "basics" because you /do/ need or want them.  It's all about /you/.   
      
   Well, let's stick with C. Here are some features I use, and the C   
   equivalents (A has whatever type is needed):   
      
       M                   C   
       -------------------------------------------------------------   
       A.len               sizeof(A)/sizeof(A[0])   
      
   *  max(a, b)           (a > b ? a : b)   
      
       A.odd               A & 1, or A % 1   
      
       A.even              - you can do this one   
      
       A.msbit             (A>>31) & 1, or (A>>63) & 1   
      
       2 ** n              (1LL << n)   
       a ** b  (int)       pow(a, b) (ints cast to float, and float result)   
       x ** y  (float)     pow(x, y)   
      
       A.[i] = x           - you can do this too; assume x is 0 or 1   
      
       A.[i..j] = x        - yikes!   
      
   *  if c in 'A'..'Z'    if (c >= 'A' && c <= 'Z')   
      
   *  if c in [cr, lf]    if (c == cr || c == lf)   
      
   *  if a = b = c        if (a == b && b == c)   
      
   *  swap(A[i+1], A[j])  {T temp=A[i+1]; A[i+1]=A[j]; A[j]=temp;}   
      
       abs(x)              abs(x), labs(x), llabs(x), fabs(x) ...   
      
       println =a, =b      printf("A=%X B=%Y\n", a, b); what are X, Y?   
      
       readln a, b         - some scanf nonsense   
      
       (a,b):=c divrem d   - involves div_t and div()   
      
       print "-" * 50      "----------------------- ... "   
      
       A[i, j]             A[i][j]   
      
       byte                unsigned char, uint8_t, _BitInt(8), char maybe   
      
      
   (* marks examples that are problemetic in C when operands that have   
   side-effects are evaluated twice)   
      
   There are /dozens/ of examples like this that make small tasks a   
   pleasure to write, but also make them clearer, to the point, and less   
   error prone.   
      
   But let me guess, none of this cuts any ice at all. The C will always be   
   superior.   
      
   > You are talking nonsense.   
      
   End of discussion then. You either missed my point or chose to ignore it.   
      
   > I understand that simple maths and common sense is beyond you.   
      
   More insults.   
      
   >>> uint64_t get_exponent(double x) {   
   >>>      return ((union { double d; uint64_t u;}) { x }.u >> 52)   
   >>>               & ((1ull << (62 - 52 + 1)) - 1);   
   >>> }   
   >>>   
   >>> That compiles (with gcc on x86-64) to :   
   >>>   
   >>>      movq rax, xmm0   
   >>>      shr rax, 52   
   >>>      and eax, 2047   
   >>>      ret   
   >>>   
   >>> There's nothing in C that suggests this must be put in memory or do   
   >>> anything more than this.   
   >>   
   >> (This only seems to work with gcc. Clang and MSVS don't like it.)   
   >>   
   >   
   > I think you are mistaken.  clang is fine with it.  It is standard C99,   
   > so any decent C compiler from the last 25 years will handle it fine.  MS   
   > gave up on bothering to make C compilers before the turn of the century   
   > (they make a reasonable enough C++ compiler).  Even your hero tcc is   
   > fine with it (though on my attempts, it produces rubbish code - maybe it   
   > needs different flags for optimisation).  The C code is not made invalid   
   > by the existence of C90-only compilers.   
      
   I was mistaken. I used godbolt.org but it was set to C++. Presumably gcc   
   has some C++ extensions that make it valid.   
      
   --- SoupGate-Win32 v1.05   
    * Origin: you cannot sedate... all the things you hate (1:229/2)   

[   << oldest   |   < older   |   list   |   newer >   |   newest >>   ]


(c) 1994,  bbs@darkrealms.ca