From: already5chosen@yahoo.com   
      
   On Wed, 07 Jan 2026 16:00:19 -0800   
   Keith Thompson wrote:   
      
   > 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)   
   >    
      
   When n declared as 'unsigned long' derectly rather than via unint32_t   
   alias than the answer is 'no'.   
      
   > 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.   
   >    
      
   It depends on how n declared.   
   When it declared as 'unsigned long' then "lu" is not uglier.   
   When it is defined as uint32_t it is uglier, despite the fact that on   
   absolute majority of the targets that I care about the latter is an   
   alias of the former.   
      
   > > 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.   
   >    
      
   No, it is correct on all implementation. Idea that in C, as opposed to   
   C++, two unsigned integer types of the same size are somehow   
   different is, IMHO, an abomination. And that is one not especially   
   common case in which I don't care about opinion of the Standard.   
      
   > 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?   
   >    
      
   If it was named 'ulong' I'd seriously consider such solution. But when   
   the name of type is not just rather long, but consists of two words as   
   well, I wouldn't do it.   
      
   > 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.   
   >   
      
   I also don't care. Since for more than decade* I didn't have target   
   with 'int' shorter than 32 bits, I just use %u. It takes me zero   
   thinking.   
   BTW, I am always aware of exact sizes of the basic types of the target   
   that I work on. I don't feel comfotable without such knowledge. That   
   how my mind works. It has problems with too abstract abstractions.   
      
   ------   
   * - or may be a little less than decade, I don't remember in which year   
    exactly I did last change to project that runs on TI C2000, which is   
    32-bit CPU, BTW, but TI being TI still had size of int that they   
    had chosen.   
      
   --- SoupGate-Win32 v1.05   
    * Origin: you cannot sedate... all the things you hate (1:229/2)   
|