Path: csiph.com!eternal-september.org!feeder.eternal-september.org!nntp.eternal-september.org!.POSTED!not-for-mail From: Keith Thompson Newsgroups: comp.lang.c Subject: Re: printf and time_t Date: Sun, 11 Jan 2026 04:59:47 -0800 Organization: None to speak of Lines: 80 Message-ID: <87ikd82tks.fsf@example.invalid> References: <10jfol6$2u6r8$1@news.xmission.com> <10jfs23$2liif$1@dont-email.me> <20260105105138.00005f0a@yahoo.com> <10jgbp7$2vdjt$1@news.xmission.com> <10jgdu9$2t8dh$1@nntp.eternal-september.org> <10jhkso$3c9r2$3@nntp.eternal-september.org> <20260106112938.00004446@yahoo.com> <10jj9st$3jbe4$2@dont-email.me> <20260106200522.000015ea@yahoo.com> <87h5sy2rlb.fsf@example.invalid> <87qzs1gliq.fsf@example.invalid> <20260108012620.000041a9@yahoo.com> <87bjj5gei4.fsf@example.invalid> <20260108023846.0000260c@yahoo.com> <10jpi8h$15aea$1@dont-email.me> <20260109141859.00004f22@yahoo.com> <10jv3rb$15aea$2@dont-email.me> <20260111132015.000026ad@yahoo.com> MIME-Version: 1.0 Content-Type: text/plain Injection-Date: Sun, 11 Jan 2026 12:59:48 +0000 (UTC) Injection-Info: dont-email.me; posting-host="86b8f0c246140a3cc0a90715ecfed66b"; logging-data="4098408"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX1+jb3bVtJtIN6Wf5zBGKEtB" User-Agent: Gnus/5.13 (Gnus v5.13) Cancel-Lock: sha1:qZVYtLkJx6dXg/HE//95qWFQIvo= sha1:vEDHG2zkMmjfUaSYsGb/qwdxNqI= Xref: csiph.com comp.lang.c:396342 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 */