Post by Jerry StucklePost by s***@casperkitty.comOn 1980s Macintosh C compilers, a string literal starting with "\p"
would be preceded by a length byte. An absolutely essential extension
when writing Macintosh applications, since the OS functions all expected
pointers to length-prefixed strings.
So, who cares what non-compliant compilers did? A properly designed C
library would handle the specific OS requirement without breaking
conformance.
The Standard allows compilers to add additional backslash escapes as an
extension. The implementation came with bundled libraries for file I/O,
but and I think its OS interface libraries included some functions that
would convert C strings to Pascal strings and then perform an OS request
(e.g. to render a string onto a GrafPort using its current selected font)
but calling a function which would copy a C string to a separate buffer
and then pass that to the OS was slower than simply using Pascal strings
when communicating with OS code that needed them.
Post by Jerry StucklePost by s***@casperkitty.comFunctions which needed to operate on strings longer than 256 bytes generally
used handles to objects which the OS could relocate as needed so as to avoid
fragmentation.
See above.
Using OS-managed handles made it possible to grow and shrink large strings
without fragmentation killing everything, at least if there weren't too many
immovable objects fragmenting the free store. While code could use malloc,
realloc, and free, application performance would often be better if programs
used the system's relocatable memory handles instead when practical.
Post by Jerry StucklePost by s***@casperkitty.comThey're pretty terrible for most purposes. If one wants to concatenate
two strings and doesn't knows the lengths, memcpy() will be faster and in
pretty much every way better than strcat(). If one doesn't know the
lengths, but somehow knows that the destination is big enough, strcat()
might be usable I suppose, but using strlen on strings whose length isn't
known, ensuring that adequate space exists, and then using memcpy, seems
like a better approach than giving the strings to strcat and hoping nothing
blows up.
C is not a great language for handling strings. But adding a length to
the string wouldn't make it any better.
Allowing the byte identified by a "string pointer" to indicate whether the
pointer identifies:
A string of a given length that precisely fills its buffer
An empty buffer of a given size
A buffer of a given size which is not completely full, and has the number
of slack bytes stored at the end.
A string descriptor which starts with a couple bytes describing what it
is, along with a pointer to the buffer, its size, the length of string
therein, and optional information allowing the buffer to be resized.
would make it possible to have a function like "strcat" whose first argument
can be a fixed-size buffer, a descriptor of a fixed-size block of storage,
or a descriptor for a resizable block of storage, and whose second argument
could be any kind of string or string descriptor, without having to pass it
anything except two string pointers. A string buffer would have to be
initialized prior to use, but that would only require storing 1-5 bytes to
it, depending upon length.
The biggest obstacle to using such strings is the lack of any decent way
to include string literals in-line within C code. If the language supported
static compound literals and a construct like:
(constExpr ? (void*)&staticCompoundLiteral1 : (void*)&staticCompoundLiteral2)
would only generate one of them, code could be written more cleanly using
prefixed strings than C strings.
Post by Jerry StuckleAnd memcpy does not add the trailing null character.
It will copy any trailing null character which is present in the original if
the null byte is included in the size.
Post by Jerry StuckleWe all know you don't like C. So why don't you find a language you do
like and stop wasting bandwidth bitching about C? No one here cares.
Low-level C is the best language for embedded systems. Today's compiler
writers, however, prefer to process a different language which is less
suitable for such purposes.