Path: csiph.com!eternal-september.org!feeder.eternal-september.org!reader01.eternal-september.org!.POSTED!not-for-mail
From: Tim Rentsch
Newsgroups: comp.lang.c
Subject: Re: C String terminator
Date: Sun, 16 Feb 2020 02:25:55 -0800
Organization: A noiseless patient Spider
Lines: 63
Message-ID: <861rquhlqk.fsf@linuxsc.com>
References: <87muaoimkt.fsf@nosuchdomain.example.com> <87a76ofad3.fsf@bsb.me.uk> <87muaodqqn.fsf@bsb.me.uk> <87zhencyud.fsf@bsb.me.uk> <1by2u7s456.fsf@pfeifferfamily.net> <87o8v3cg0i.fsf@bsb.me.uk> <877e1rc6f7.fsf@bsb.me.uk> <87v9p9bylk.fsf@bsb.me.uk> <861rrtj9hx.fsf@linuxsc.com> <87d0bc8xf6.fsf@nosuchdomain.example.com>
Mime-Version: 1.0
Content-Type: text/plain; charset=us-ascii
Injection-Info: reader02.eternal-september.org; posting-host="5afe6ca82d77f883ab9def33834e0994"; logging-data="11607"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX1/4sdPGONVR5fhzRzCfGlksPYCfv6QsMn0="
User-Agent: Gnus/5.11 (Gnus v5.11) Emacs/22.4 (gnu/linux)
Cancel-Lock: sha1:6d4eyRqhwnHZLJ5PvSaLGPGvjto= sha1:e/8KZYEV24+f0+4x6OEMTQt1Kzg=
Xref: csiph.com comp.lang.c:150040
Keith Thompson writes:
> Tim Rentsch writes:
>
>> Lew Pitcher writes:
>
> [...]
>
>>> Correction #1: in this case, the critical point is that, here,
>>> printf() expects a C "string" as it's second argument (as well as
>>> the first argument, which is the given format string "[%s]\n").
>>
>> Technically, that isn't right. A %s conversion specifier requires
>> as its argument a pointer to the first element of an array of
>> character type, not a pointer to a string. It is true in this
>> particular case that the array must have a null character in it to
>> avoid undefined behavior, but the argument description says "pointer
>> to array of character type", and does not mention "string".
>>
>> (Also: the possessive of "it" is "its", with no apostrophe. The
>> word "it's", with an apostrophe, is a contraction of "it is".)
>
> I believe the reason it's described that way is that %s with a field
> width can require a pointer that isn't necessarily a pointer to a
> string. [..example..]
The passage in question is part of paragraph 8 in section 7.21.6.1.
This paragraph describes conversion /specifiers/, not conversion
/specifications/. Considered as a conversion /specifier/, an 's'
specifier takes a pointer to (an initial element in) an array of
characters (which are wide characters if an 'l' length modifier is
present, or regular characters if not). The wording used most
likely reflects wanting to describe the 's' conversion specifier
generally, rather than particular conversion specifications that
use an 's' specifier.
Incidentally, it's precision, not field width.
> The standard *could* have equivalently stated that a pointer to a
> string is required when the format contains a "%s" directive, but
> that would have made it overly wordy with no clear benefit.
More significantly, it would have been inconsistent with other parts
of the same paragraph, which defines the semantics of conversion
specifiers, not of whole conversion specifications (which are also
called directives). It would be out of place in this paragraph to
talk about a particular directive that contains an 's' specifier (and
besides which is incomplete, because there are other cases where the
character array needs to have a null character).
> A pointer to a string *is* required for a "%s" directive, but the
> standard says so only indirectly.
I have some quibbles about the wording here, but more importantly I
think this is a bad way to take in what the Standard does say. What
the Standard does say is that an 's' specifier takes a pointer to an
array of character type, which in some situations much include a
null character within the array (and a %s specification is one of
those). It can be convenient to think of a %s directive as needing
a string argument, but the Standard doesn't say anything about
strings in its description of 's' specifiers, only arrays of
character type. In some cases an array argument needs to contain a
string, but the argument is still the array, not the string.