Path: ...!fu-berlin.de!eternal-september.org!feeder3.eternal-september.org!news.eternal-september.org!.POSTED!not-for-mail From: Keith Thompson Newsgroups: comp.lang.c Subject: Re: "undefined behavior"? Date: Thu, 13 Jun 2024 17:09:48 -0700 Organization: None to speak of Lines: 70 Message-ID: <878qz85qr7.fsf@nosuchdomain.example.com> References: <666a095a$0$952$882e4bbb@reader.netnews.com> <8t3k6j5ikf5mvimvksv2t91gbt11ljdfgb@4ax.com> <666a18de$0$958$882e4bbb@reader.netnews.com> <87y1796bfn.fsf@nosuchdomain.example.com> <666a2a30$0$952$882e4bbb@reader.netnews.com> <87tthx65qu.fsf@nosuchdomain.example.com> <87plsk5xbz.fsf@nosuchdomain.example.com> MIME-Version: 1.0 Content-Type: text/plain Injection-Date: Fri, 14 Jun 2024 02:09:49 +0200 (CEST) Injection-Info: dont-email.me; posting-host="10f324c947246626491173dedfdc5917"; logging-data="2650136"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX1838Vp461GGqbfnOHpnTbT9" User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/27.2 (gnu/linux) Cancel-Lock: sha1:sfabvF0RBKD1RAL1UfZPM2oSGO4= sha1:hKMsqzDiT1if2ldktUXQkaDdb8o= Bytes: 4612 Malcolm McLean writes: > On 13/06/2024 22:47, Keith Thompson wrote: >> Malcolm McLean writes: >>> On 13/06/2024 01:33, Keith Thompson wrote: >>>> printf is a variadic function, so the types of the arguments after >>>> the format string are not specified in its declaration. The printf >>>> function has to *assume* that arguments have the types specified >>>> by the format string. This: >>>> printf("%d\n", foo); >>>> (probably) has undefined behavior if foo is of type size_t. >>>> >>> And isn't that a nightmare? >> Not at all. Compilers commonly diagnose mismatches when the format >> string is a string literal, as it most commonly is. The format >> specifier for size_t is "%zu", since C99. >> >>>> There is no implicit conversion to the expected type. Note that >>>> the format string doesn't have to be a string literal, so it's >>>> not always even possible for the compiler to check the types. >>>> Variadic functions give you a lot of flexibility at the cost of >>>> making some type errors difficult to detect. >>>> (I wrote "probably" because size_t *might* be a typedef for unsigned >>>> int, and there are special rules about arguments of corresponding >>>> signed and unsigned types.) >>> >>> We just can't have size_t variables swilling around in prgrams for >>> these reasons. >> We can and do. >> > And this is how things break. > > Now, running a third party editor under your control so that user can > edit an text and return control and the edited text back to you when > he exits the editor. Yes, I understand that this is a difficult thing > to do, the software engineeering isn't consistent, and theway you have > to do it may change from one version of C to another. > But printing out a variable which holds the length of a string? And > something so basic breaks from one version of C to the next? We should > ahave no tolerance for that at all. What broke? And how would *you* print the result of strlen()? strlen() has returned a result of type size_t since C89/C90. C99 (that's 25 years ago) added the "%zu" format specifier. Today, you're unlikely to find an implementation that doesn't support printf("%zu\n", strlen(s)); But even if you need to deal with pre-C99 implementations for some reason, this: printf("%lu\n", (unsigned long)(strlen(s)); works reliably in C90, and works in C99 and later as long as size_t is no wider than unsigned long -- and even then it breaks (printing an incorrect value) only if the actual value returned by strlen(s) exceeds ULONG_MAX, which is at least 4294967295. If you're using 4-gigabyte strings, you probably want to avoid calling strlen() on them anyway. This: printf("%d\n", strlen(s)); has *never* been valid (it has undefined behavior unless the implementation you're using happens to make size_t a typedef for unsigned int and the value doesn't exceed INT_MAX, which might be as small as 32767). We're simply not going to throw away the last quarter century of progress in C and go back to C90. You can if you like, but don't expect anyone else to follow you. -- Keith Thompson (The_Other_Keith) Keith.S.Thompson+u@gmail.com void Void(void) { Void(); } /* The recursive call of the void */