Deutsch   English   Français   Italiano  
<878qz85qr7.fsf@nosuchdomain.example.com>

View for Bookmarking (what is this?)
Look up another Usenet article

Path: ...!fu-berlin.de!eternal-september.org!feeder3.eternal-september.org!news.eternal-september.org!.POSTED!not-for-mail
From: Keith Thompson <Keith.S.Thompson+u@gmail.com>
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>
	<v4dtlt$23m6i$1@dont-email.me>
	<87plsk5xbz.fsf@nosuchdomain.example.com>
	<v4g02k$2gfm9$2@dont-email.me>
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 <malcolm.arthur.mclean@gmail.com> writes:
> On 13/06/2024 22:47, Keith Thompson wrote:
>> Malcolm McLean <malcolm.arthur.mclean@gmail.com> 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 */