From: Keith.S.Thompson+u@gmail.com   
      
   Michael S writes:   
   > On Sat, 10 Jan 2026 22:02:03 -0500   
   > "James Russell Kuyper Jr." wrote:   
   >> On 2026-01-09 07:18, Michael S wrote:   
   >> > On Thu, 8 Jan 2026 19:31:13 -0500   
   >> > "James Russell Kuyper Jr." wrote:   
   >> ...   
   >> >> I'd have no problem with your approach if you hadn't falsely   
   >> >> claimed that "It is correct on all platforms".   
   >> >   
   >> > Which I didn't.   
   >>   
   >> On 2026-01-07 19:38, Michael S wrote:   
   >> ...   
   >> > No, it is correct on all implementation.   
   >   
   > The quote is taken out of context.   
   > The context was that on platforms that have properties (a) and (b) (see   
   > below) printing variables declared as uint32_t via %u is probably UB   
   > according to the Standard (I don't know for sure, however it is   
   > probable),   
      
   I'm sure. uint32_t is an alias for some predefined integer type.   
      
   This:   
    uint32_t n = 42;   
    printf("%u\n", n);   
   has undefined behavior *unless* uint32_t happens to an alias for   
   unsigned int in the current implementation -- not just any 32-bit   
   unsigned integer type, only unsigned int.   
      
   If uint32_t is an alias for unsigned long (which implies that   
   unsigned long is exactly 32 bits), then the call's behavior is   
   undefined. (It might happen to "work".)   
      
   If uint32_t and unsigned long have different sizes, it still might   
   happen happen to "work", depending on calling conventions. Passing a   
   32-bit argument and telling printf to expect a 64-bit value clearly has   
   undefined behavior, but perhaps both happen to be passed in 64-bit   
   registers, for example.   
      
   > but it can't cause troubles with production C compiler. Or   
   > with any C compiler that is made in intention of being used rather than   
   > crafted to prove theoretical points.   
   > Properties are:   
   > a) uint32_t aliased to 'unsigned long'   
      
   Not guaranteed by the language (and not true on the implementations   
   I use most often).   
      
   > b) 'unsigned int' is at least 32-bit wide.   
      
   Not guaranteed by the language (though it happens to be guaranteed by   
   POSIX).   
      
   > I never claimed that it is good idea on targets with 'unsigned int'   
   > that is narrower.   
      
   I claim that it's not a good idea on any target.   
      
   I find it *much* easier to write portable code than to spend time   
   figuring out what non-portable code will happens to work on the   
   platforms I happen to care about today.   
      
    uint32_t n = 42;   
    printf("%lu\n", (unsigned long)n);   
      
   unsigned long is guaranteed by the language to be at least 32 bits.   
   The conversion is guaranteed not to lose information. The format   
   matches the type of the argument. And the code will work correctly   
   on any conforming hosted implementation. (It might involve an   
   unnecessary 32 to 64 bit conversion, but given the overhead of   
   printf, that's unlikely to be a problem -- and if it is, I can use   
   the appropriate macro from .)   
      
   And to my eyes, using "%u" with a uint32_t argument is *ugly*.   
      
   --   
   Keith Thompson (The_Other_Keith) Keith.S.Thompson+u@gmail.com   
   void Void(void) { Void(); } /* The recursive call of the void */   
      
   --- SoupGate-Win32 v1.05   
    * Origin: you cannot sedate... all the things you hate (1:229/2)   
|