From: msb@sq.sq.com (Mark Brader)
Subject: Definition of string (was: Strings and integer sizes)
Supersedes: <1992Oct14.054345.18892@sq.sq.com>
Organization: SoftQuad Inc., Toronto, Canada
Date: Wed, 14 Oct 92 05:57:51 GMT

[Corrected version; you should not see the other; apologies if you did.]

> > >  (It's been mentioned several times during this thread, but "string"
> > >  is a weakly-defined concept in C, not a formal part of the language
> > >  except by convention, and by the fact that string literals generate
> > >  them and many standard library routines expect them.)
> > 
> > I believe that string is quite well-defined: it's a constant.
> 
> Don't you mean "string literal"?

Actually, I think this is another area where ANSI C differs from
traditional C.  I believe it's fair to say that "string" was weakly
defined in traditional usage, at least informally, even if there is
an exact definition lurking in K&R.

One of the benefits of the standardization has been stricter definition,
and so it is here.  The ANSI standard does not introduce the term "string"
until section 4 (section 7 in the ISO version) on library functions.
At this point, right at the top (4.1.1/7.1.1), we have:

#   A _string_ is a contiguous sequence of characters terminated
#   by and including the first null character.  A "pointer to" a
#   string is a pointer to its initial (lowest addressed) character.
#   The "length" of a string is the number of characters preceding
#   the null character and its "value" is the sequence of the values
#   of the contained characters, in order.

In other words, a string in ANSI C is a data structure and not a
syntactic construct.  Those things in double quotes are _character
string literals_.  Each character string literal specifies a sequence
of characters.  If the character string literal is not adjacent to
another one, the sequence of characters has a null character appended
and the resulting sequence is used to initialize "an array of static
storage duration and length just sufficient to contain the sequence"
(quote from 3.1.4/6.1.4).

From here on in this article I'm assuming ANSI C.

If two or more character string literals are adjacent, then all their
character sequences are concatenated and _then_ a null is appended and
the resulting sequence is used as above.  This means that in *each*
of the following lines, the longest string (data structure) mentioned
has length 5 and value "hello":

	char *x = "hel" "lo";
	char *y = "hello";
	char *z = "hello\0mars";

This should illustrate the distinction between a string and a
character string literal.  For further emphasis, I point out that each
line also mentions shorter strings: length 4, value "ello"; length 3,
value "llo", and so on down to 0; and also "mars", "ars", etc. on the
third line.  Yes, these really are strings; for instance, it would
be perfectly legitimate to invoke puts("%s",x+1); to print "ello"
(and a newline), but the argument of puts() is specified as pointing
to a string.

In the construct

	char zoe[3] = { "123" };

as discussed before, only the three characters '1', '2', and '3' get
used in the initialization.  Thus the array zoe does _not_ contain a
string after this initialization.

For completeness I mention that ANSI C also has _wide string literals_,
which Look Like L"this", and work the same way except that they turn
into arrays of the type wchar_t instead of char.  When character sets
having variable-length characters are in use, the characters in a
character string literal may occupy different numbers of bytes each;
all characters in a wide string literal occupy the same width.
-- 
Mark Brader, Toronto		sed -e "s;??\\([-=(/)'<!>]\\);?\\\\?\\1;g"
utzoo!sq!msb, msb@sq.com	will fix them...	-- Karl Heuer

This article is in the public domain.