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.