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,900 of 243,242   
   Keith Thompson to Michael S   
   Re: printf and time_t   
   07 Jan 26 16:00:19   
   
   From: Keith.S.Thompson+u@gmail.com   
      
   Michael S  writes:   
   > On Wed, 07 Jan 2026 13:28:45 -0800   
   > Keith Thompson  wrote:   
   >> scott@slp53.sl.home (Scott Lurndal) writes:   
   >> > Keith Thompson  writes:   
   >> >>Michael S  writes:   
   >> >>> On Tue, 6 Jan 2026 10:31:41 -0500   
   >> >>> James Kuyper  wrote:   
   >> >>>> On 2026-01-06 04:29, Michael S wrote:   
   >> >>>> > On Tue, 6 Jan 2026 00:27:04 -0000 (UTC)   
   >> >>>> > Lawrence D’Oliveiro  wrote:   
   >> >>>> ...   
   >> >>>> >> Section 7.8 of the C spec defines macros you can use so you   
   >> >>>> >> don’t have to hard-code assumptions about the lengths of   
   >> >>>> >> integers in printf-format strings.   
   >> >>>> >   
   >> >>>> > Did you ever try to use them? They look ugly.   
   >> >>>>   
   >> >>>> Which is more important, correctness or beauty?   
   >> >>>   
   >> >>> It depends.   
   >> >>>   
   >> >>> When I know for sure that incorrectness has no consequences, like   
   >> >>> in case of using %u to print 'unsigned long' on target with 32-bit   
   >> >>> longs, or like using %llu to print 'unsigned long' on  target with   
   >> >>> 64-bit longs, then beauty wins. Easily.   
   >> >>   
   >> >>Seriously?   
   >> >>   
   >> >>An example:   
   >> >>   
   >> >>    unsigned long n = 42;   
   >> >>    printf("%u\n", n);  // incorrect   
   >> >>    printf("%lu\n", n); // correct   
   >> >>   
   >> >>Are you really saying that the second version is so much uglier   
   >> >>than the first that you'd rather write incorrect code?   
   >> >   
   >> > I suspect he may have been referring to code that needs   
   >> > to build for both 32-bit and 64-bit targets.   One might   
   >> > typedef 'uint64' to be unsigned long long on both targets   
   >> > and just use %llu for the format string.  BTDT.   
   >>   
   >> In the quoted paragraph above, Michael wrote about using %u to print   
   >> unsigned long, not about using %u to print some type hidden behind   
   >> a typedef.  If he didn't mean that, he can say so.   
   >>   
   >> But even if he meant to talk about printing, say, uint64_t values,   
   >> my point stands.   
   >>   
   >> I wouldn't define my own "uint64" type.  I'd just use "uint64_t",   
   >> defined in .  And I'd use one of several *correct* ways   
   >> to print uint64_t values.   
   >>   
   >> Michael, if you'd care to clarify, given:   
   >>   
   >>     unsigned long n = 42;   
   >>     printf("%u\n", n);  // incorrect   
   >>     printf("%lu\n", n); // correct   
   >>   
   >> (and assuming that unsigned int and unsigned long are the same width   
   >> on the current implementation), do you really prefer the version   
   >> marked as "incorrect"?   
   >   
   > I hoped that I already clarified that point more than one time.   
   > Obviously, I hoped wrong.   
      
   And you still haven't.  I asked a specific question above.  What is   
   your answer?  Would you use a "%u" format to print a value that's   
   defined with type unsigned long?  I inferred from what you wrote   
   that your answer would be yes.  If your answer is no, I'll gladly   
   accept that.  (And if so, what you wrote previously was unclear,   
   but I'm not going to worry about that if you clarify what you meant)   
      
   You've previously indicated that you find "%lu" uglier than "%u",   
   and that that's relevant to which one you would use.  Do you still   
   think so?   
      
   I would appreciate direct yes or no answers to both of those   
   questions.   
      
   > In the case I am talking about n declared as uint32_t.   
   > uint32_t is an alias of 'unsigned long' on 32-bit embedded targets, on   
   > 32-bit Linux, on  32-bit Windows and on 64-bit Windows. It is   
   > alias of 'unsigned int' on 64-bit Linux.   
   > Sometimes I move code between targets by myself, sometimes, rarely,   
   > other people do it. I don't want to have different versions of the code   
   > and I don't want to use ugly standard specifiers. Between two pretty   
   > and working variants I prefer the shorter one. Partly because it is   
   > guaranteed to work correctly on all my targets, including LIN64, but   
   > more importantly (in practice, 64-bit Linux is a very rare target in my   
   > daily routine) just because it is shorter. And I don't care that it is   
   > formally "incorrect" on my more common targets. Or may be not   
   > "formally", but both gcc and clang think so.   
      
   So you'd write code that happens to work on some implementations rather   
   than code that's correct on all implementations.   
      
   You know that unsigned long is at least 32 bits wide, and therefore that   
   converting a uint32_t value to unsigned long will not lose information,   
   and therefore that   
      
       uint32_t x = 42;   
       printf("%lu\n", (unsigned long)x);   
      
   will work correctly.  You can do this without using the ugly   
    macros.  Why wouldn't you?   
      
   Sure, you can write code that happens to work on the only implementation   
   you care about, but in my opinion, aside from being dangerous, it's just   
   too much work.  I don't care whether uint32_t is defined as unsigned int   
   or unsigned long on a particular implementation, and I don't have to care.   
      
   --   
   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)   

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


(c) 1994,  bbs@darkrealms.ca