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,946 of 243,242   
   Michael S to Keith Thompson   
   Re: printf and time_t   
   11 Jan 26 15:32:01   
   
   From: already5chosen@yahoo.com   
      
   On Sun, 11 Jan 2026 04:59:47 -0800   
   Keith Thompson  wrote:   
      
   > 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".)   
   >   
      
   What exactly, assuming that conditions (a) and (b) fulfilled, should   
   implementation do to prevent it from working?   
   I mean short of completely crazy things that will make maintainer   
   immediately fired?   
      
   > 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.   
   >   
      
   And that is sort of intimate knowledge of the ABI that I don't want to   
   exploit, as already mentioned in my other post in this sub-thread.   
      
   > >            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).   
   >   
      
   Did I ever say that it is guaranteed by the language or that it is   
   universal in any other way?   
   Normally you have much better reading comprehension than one that you   
   demonstrate in this discussion. I'd guess that it's because I somehow   
   caused you to become angry.   
      
   > > b) 'unsigned int' is at least 32-bit wide.   
   >   
   > Not guaranteed by the language (though it happens to be guaranteed by   
   > POSIX).   
   >   
      
   Did I ever say etc ...   
      
   > > 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*.   
   >   
      
   To be fair, it is not ideal.   
   The solution that I would prefer would be universal adaption of   
   Microsoft's size specifiers I32 and I64. They are not going to win   
   beauty competition, but in practice they are a lot more convenient to   
   use than standard macros and are equally good at carrying programmer's   
   intentions.   
      
   Microsoft has strong influence in committee, but was not able to push   
   it into C11, where they successfully forced hands of other members on   
   few much bigger and more controversial issues.   
   I don't know what it means, May be, there is bold technical reason   
   behind non-standardization of these size specifiers. Or may be there is   
   no reason and Microsoft simply never tried.   
      
   --- 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