10

In various bash scripts I have come across the following: $'\0'

An example with some context:

while read -r -d $'\0' line; do
    echo "${line}"
done <<< "${some_variable}"

What does $'\0' return as its value? Or, stated slightly differently, what does $'\0' evaluate to and why?

It is possible that this has been answered elsewhere. I did search prior to posting but the limited number of characters or meaningful words in dollar-quote-slash-zero-quote makes it very hard to get results from stackoverflow search or google. So, if there are other duplicate questions, please allow some grace and link them from this question.

viraptor
  • 33,322
  • 10
  • 107
  • 191
John Mark Mitchell
  • 4,522
  • 4
  • 28
  • 29
  • 1
    Possible duplicate of [this one in unix.stackexchange.com](http://unix.stackexchange.com/questions/223823/null-and-escape-characters#223837) – Ezequiel Tolnay Apr 13 '16 at 02:56
  • Also could be considered a dupe of [this one](http://stackoverflow.com/questions/19227564/why-0-or-x0-is-an-empty-string-should-be-the-null-character-isnt-it) on Stack Overflow. – user2357112 Apr 13 '16 at 02:59
  • 1
    Aside: Using `echo` here is very much suboptimal. See the POSIX spec for `echo` at http://pubs.opengroup.org/onlinepubs/009604599/utilities/echo.html -- it has a *huge* amount of undefined behavior. (Is your string `-n`? Behavior undefined. Does your string contain a backslash literal anywhere? Behavior undefined. And if your string is `-e` or `-E`, then behavior is well-defined by POSIX, but you're likely to have an implementation that defies the standard -- unless you have the `xpg_echo` option set. – Charles Duffy Apr 13 '16 at 03:49
  • 2
    I imagine the level of pedantry and hair-splitting is more than you bargained for in asking this question -- but with all answers taken together, you presumably have a very comprehensive understanding of the matter at hand, or at minimum plenty of places from which to launch further research or follow-up questions. :) – Charles Duffy Apr 13 '16 at 22:07
  • 2
    @CharlesDuffy I agree. Amidst all the hair-splitting, people were kind and helpful. It was \informative to reading the answers and the comments on each. In total, it has given me a much better understanding of what is happening. In particular, I learned 1) that the `$'\0'` was an ANSI C-quoted string 2) that in Bash strings are NUL terminated. Both of those were new to me. – John Mark Mitchell Apr 13 '16 at 22:24
  • @CharlesDuffy I will assume that the word "pedantry" is a reflection of the way you think, a simple look in the mirror if you wish. –  Apr 13 '16 at 22:25
  • 1
    @BinaryZebra, indeed, I was poking a bit of fun at myself above. – Charles Duffy Apr 13 '16 at 22:40
  • @CharlesDuffy You have my full permissions to poke at yourself all you wish. –  Apr 13 '16 at 23:12

4 Answers4

16

In bash, $'\0' is precisely the same as '': an empty string. There is absolutely no point in using the special Bash syntax in this case.

Bash strings are always NUL-terminated, so if you manage to insert a NUL into the middle of a string, it will terminate the string. In this case, the C-escape \0 is converted to a NUL character, which then acts as a string terminator.

The -d option of the read builtin (which defines a line-end character the input) expects a single character in its argument. It does not check if that character is the NUL character, so it will be equally happy using the NUL terminator of '' or the explicit NUL in $'\0' (which is also a NUL terminator, so it is probably no different). The effect, in either case, will be to read NUL-terminated data, as produced (for example) by find's -print0 option.

In the specific case of read -d '' line <<< "$var', it is impossible for $var to have an internal NUL character (for the reasons described above), so line will be set to the entire value of $var with leading and trailing whitespace removed. (As @mklement notes, this will not be apparent in the suggested code snippet, because read will have a non-zero exit status, even though the variable will have been set; read only returns success if the delimiter is actually found, and NUL cannot be part of a here-string.)

Note that there is a big difference between

read -d '' line

and

read -d'' line

The first one is correct. In the second one, the argument word passed to read is just -d, which means that the option will be the next argument (in this case, line). read -d$'\0' line will have identical behaviour; in either case, the space is necessary. (So, again, no need for the C-escape syntax).

rici
  • 234,347
  • 28
  • 237
  • 341
  • 1
    Great answer. It's a code style thing. I write `$'\0'` to make my intentions clear. – John Kugelman Apr 13 '16 at 03:10
  • @rici when you said "no need for the C-escape syntax" are you saying that `read -d ''` has the same result as `read -d $'\0'`? In effect, both result in read using the NUL char as the line-end character? – John Mark Mitchell Apr 13 '16 at 03:10
  • 2
    @JohnMarkMitchell: Yes. There is absolutely no detectable difference between `''` and `$'\0'`. (And, I believe, there is really no difference internally either.) – rici Apr 13 '16 at 03:14
  • No, `$'\0' is precisely the same as '': an empty string` that's not true (always), and in fact, it doesn't have to be. –  Apr 13 '16 at 05:28
  • @binaryZebra: Remembering that we're talking about bash, would you care to provide an example which shows different behaviour? – rici Apr 13 '16 at 05:44
  • @rici I could provide some `\0` examples: `printf 'ab\0cd' | od -An -vtx1`. And we should be aware that in zsh `a="$(printf 'ab\0cd')"; echo "$a"` will contain an ASCII NUL byte (with value `0x00`). And I believe that zsh is an useful shell which should not be completely discarded. –  Apr 13 '16 at 06:01
  • @rici The question is (also) about the effect of `$'\0'` on `read`, which is that `read` will read up to the next `$'\0'` (yes, a mouthful, but correct). That is absolutely **not** the same as saying that `read` will read till the next "empty" byte. –  Apr 13 '16 at 06:06
  • 2
    @binaryzebra: your printf example does not use `$'\0'`; in that casethe backslash and 0 are being passed to printf. I have nothing against zsh, which as you say is useful, but this question is clearly about bash, and so is my answer. There is no such thing as an empty byte, and I have not used that phrase. So I stand by my claim that in bash, `''` and `$'\0'` are indistinguishable. – rici Apr 13 '16 at 06:16
  • @rici Would you be so kind to tell me what character value is used by `read` to split the input on this command: `read -r -d $'\0'`, thanks. –  Apr 13 '16 at 19:21
  • @BinaryZebra, which claim made prior in this comment thread would the answer to that question refute? – Charles Duffy Apr 13 '16 at 20:14
  • @CharlesDuffy The statement that `'' and $'\0' are indistinguishable` fails to acknowledge the fact that a '0x00' is used to split the input by the command of `read` presented as example by the OP, and therefore may confuse the reader. A `read -r -d $'\0'` is more explicit about that IMhO. –  Apr 13 '16 at 20:22
  • 1
    @BinaryZebra, ...whether or not a NUL byte is or is not used to split the input has no bearing on whether the conventions are distinguishable -- that is, whether the implementation of `read` has any way to tell which of two relevant possibilities it was passed (thus *distinguishing* between the two). – Charles Duffy Apr 13 '16 at 20:23
  • @CharlesDuffy The command read has no way to distinguish between `$'\0'` and `''`, yes, that's technically true. The same as tabs are irrelevant to commands but very useful to users to format code. And humans reading the command (and translating that to "an idea") will get and read different text and may get different "meaning" in both cases. They may even get the incorrect meaning. –  Apr 13 '16 at 21:34
  • @BinaryZebra, I agree that different human encodings of a given parse tree or argument string can have pertinent differences for readability, but if we interpret "distinguishable" as a term of art (which is how I read rici's statement above, expanding "to bash" as "to the bash interpreter", ie. how the parse result is viewed *by bash itself*), human-readability matters are not pertinent to the factuality of rici's claim. – Charles Duffy Apr 13 '16 at 21:49
  • @CharlesDuffy If both are in-distinguishable, then either could be used to represent the exact same technical value. It is then a matter of "personal expression" to make intentions clear. –  Apr 13 '16 at 21:51
  • @BinaryZebra, indeed so. (Does the above comment attempt to refute any prior statement or claim in this thread?) – Charles Duffy Apr 13 '16 at 21:53
  • @CharlesDuffy Only that it is better to write `read -r -d $'\0'` instead of `read -r -d ''` and that that is not in-distinguishable to the reader. –  Apr 13 '16 at 21:59
  • I think it's understood at this point that we agree to disagree as to which kind of potential misunderstanding we prefer our code to promote. :) – Charles Duffy Apr 13 '16 at 22:01
  • @CharlesDuffy How you write your code is entirely your choice. But the fact remains that the two ways to write the code are distinguishable. –  Apr 13 '16 at 22:08
  • Not distinguishable **to bash**, ie., the interpreter itself, no. I consider any other interpretation a misreading so severe as to be presumptively deliberate and thus a strawman argument, though it would be rici who could speak definitively to the intent of the language at hand. (If it had been "in bash" rather than "to bash", that could be reasonably interpreted as meaning-to-humans rather than meaning-to-the-parser, but the use of the word "to" is entirely clear). – Charles Duffy Apr 13 '16 at 22:09
  • @CharlesDuffy The first sentence of this answer does say `**In** bash, $'\0' is precisely...`. Also state: `There is absolutely no point in using the special Bash syntax in this case.`. It has become patently clear that both ways are **not** equivalent. It also state (incorrectly) that `if you manage to insert a NUL into the middle of a string, it will terminate the string`. If a string with an inserted `NUL` is assigned to a variable, the NUL is **removed**, the string is **not** terminated. Just three of the mistakes included. –  Apr 13 '16 at 22:23
  • 1
    @BinaryZebra, your claims are not fully correct. For instance, re: "If a string with an inserted NUL is assigned to a variable" -- it depends on exactly where it's coming from. `foo=$(bar)` will eliminate a NUL in the output of `bar`, but that's not the assignment doing the elimination but the command substitution. For the assignment, the NUL **does** in fact terminate the string. – Charles Duffy Apr 13 '16 at 22:43
  • @BinaryZebra, ...as for repointing your existing critique against the first sentence rather than the context to which you initially asked that it be applied, if we wanted to quibble about different types and meanings of "equivalent", we could do that, but I honestly can't see much value in the exercise; absent seeing eye-to-eye with you on that point, I can't agree with your claim that that first sentence is in fact inaccurate. – Charles Duffy Apr 13 '16 at 22:46
  • 1
    @BinaryZebra, ...I will grant you only that "there is absolutely no point" could indeed be amended to "there is absolutely no non-stylistic point", or similar. – Charles Duffy Apr 13 '16 at 22:47
  • @CharlesDuffy Could you be so kind as to provide an example of `For the assignment, the NUL does in fact terminate the string.` (not a command substitution of course). –  Apr 13 '16 at 23:15
  • @CharlesDuffy I am not claiming anything about the `In bash`, just telling you that you are incorrectly stating that a `to bash` was used when in fact it was not. –  Apr 13 '16 at 23:17
  • @CharlesDuffy By the actual experience on this thread I believe that there is no point if you grant anything. –  Apr 13 '16 at 23:19
  • 1
    @BinaryZebra: To reiterate what Charles said: it is the _command substitution_ that _strips_ the NULs, not the _assignment_. Here's an assignment that does cut off at NUL: `printf -v var 'a\0b'; printf %s "$var" | cat -v`. I would also like to take a moment to reflect on how your combative attitude, cantankerousness, and ad-hominem attacks have really been unpleasant to witness and endure. What could have been an interesting and fruitful dialog (and was, between the rest of us) turned sour. – mklement0 Apr 14 '16 at 02:04
  • @mklement0 The only bad comment was done by Charles Duffy: `pedantry and hair-splitting`, not me. –  Apr 14 '16 at 02:22
  • @BinaryZebra: Yes, it outputs `a`, which means that it _cuts off_ (at the first NUL). If it stripped, you'd get `ab` - which is what you do get with `var=$(printf 'a\0b')`, because the command substitution _strips_. – mklement0 Apr 14 '16 at 02:25
  • @mklement0 The only reason it has not been "fruitful" is because you are only centered on making me changing my opinion (which is correct anyway), instead on trying to understand **what** is being said. An example is your division on: "the rest of us" and "you". So, in your words you imply that: I am the odd one. What do you want me to do on that? To say: yes I am the only wrong one sorry everyone? No, that is not what should happen, and will not happen. –  Apr 14 '16 at 02:28
  • @mklement0 Ah, sorry, I swaped the understanding of the words. I understand what you mean, now. I'll get back to this latter. –  Apr 14 '16 at 02:30
  • @mklement0 I do not know how we walked into a disagreement about cut, strip, terminate or ignore a NUL, nor what I was thinking at the time, but I actually misspoke when I said that: `If a string with an inserted NUL is assigned to a variable, the NUL is removed, the string is not terminated.` I do know the opposite is true. And that is clear in my rewritten answer. –  Apr 14 '16 at 03:34
  • 1
    @BinaryZebra, I consider pedantry and hair-splitting to be worthwhile endeavours -- making sure that peoples' understanding of a topic is accurate, precise and well-defined is a valuable pursuit when working in a field where details matter. Yes, I used those words poking fun at myself, but it was intended to be in a good-natured manner. – Charles Duffy Apr 14 '16 at 15:21
  • 1
    @CharlesDuffy All is well that ends well. I'll take all in a good-natured manner and move forward. :-) –  Apr 14 '16 at 23:23
5

To complement rici's helpful answer:

Note that this answer is about bash. ksh and zsh also support $'...' strings, but their behavior differs:
* zsh does create and preserve NUL (null bytes) with $'\0'.
* ksh, by contrast, has the same limitations as bash, and additionally interprets the first NUL in a command substitution's output as the string terminator (cuts off at the first NUL, whereas bash strips such NULs).

$'\0' is an ANSI C-quoted string that technically creates a NUL (0x0 byte), but effectively results in the empty (null) string (same as ''), because any NUL is interpreted as the (C-style) string terminator by Bash in the context of arguments and here-docs/here-strings.

As such, it is somewhat misleading to use $'\0' because it suggests that you can create a NUL this way, when you actually cannot:

  • You cannot create NULs as part of a command argument or here-doc / here-string, and you cannot store NULs in a variable:

    • echo $'a\0b' | cat -v # -> 'a' - string terminated after 'a'
    • cat -v <<<$'a\0b' # -> 'a' - ditto
  • In the context of command substitutions, by contrast, NULs are stripped:

    • echo "$(printf 'a\0b')" | cat -v # -> 'ab' - NUL is stripped
  • However, you can pass NUL bytes via files and pipes.

    • printf 'a\0b' | cat -v # -> 'a^@b' - NUL is preserved, via stdout and pipe
    • Note that it is printf that is generating the NUL via its single-quoted argument whose escape sequences printf then interprets and writes to stdout. By contrast, if you used printf $'a\0b', bash would again interpret the NUL as the string terminator up front and pass only 'a' to printf.

If we examine the sample code, whose intent is to read the entire input at once, across lines (I've therefore changed line to content):

while read -r -d $'\0' content; do  # same as: `while read -r -d '' ...`
    echo "${content}"
done <<< "${some_variable}"

This will never enter the while loop body, because stdin input is provided by a here-string, which, as explained, cannot contain NULs.
Note that read actually does look for NULs with -d $'\0', even though $'\0' is effectively ''. In other words: read by convention interprets the empty (null) string to mean NUL as -d's option-argument, because NUL itself cannot be specified for technical reasons.

In the absence of an actual NUL in the input, read's exit code indicates failure, so the loop is never entered.

However, even in the absence of the delimiter, the value is read, so to make this code work with a here-string or here-doc, it must be modified as follows:

while read -r -d $'\0' content || [[ -n $content ]]; do
    echo "${content}"
done <<< "${some_variable}"

However, as @rici notes in a comment, with a single (multi-line) input string, there is no need to use while at all:

read -r -d $'\0' content <<< "${some_variable}"

This reads the entire content of $some_variable, while trimming leading and trailing whitespace (which is what read does with $IFS at its default value, $' \t\n').
@rici also points out that if such trimming weren't desired, a simple content=$some_variable would do.

Contrast this with input that actually contains NULs, in which case while is needed to process each NUL-separated token (but without the || [[ -n $<var> ]] clause); find -print0 outputs filenames separated by a NUL each):

while IFS= read -r -d $'\0' file; do
    echo "${file}"
done < <(find . -print0)

Note the use of IFS= read ... to suppress trimming of leading and trailing whitespace, which is undesired in this case, because input filenames must be preserved as-is.

Community
  • 1
  • 1
mklement0
  • 382,024
  • 64
  • 607
  • 775
  • If trimming were not desired, the robust solution would be `content=$some_variable`; all the rest is obfuscation. But I suspect trimming was intentional; it's actually a reasonably clever implementation of trim, except for the `while` of course. – rici Apr 13 '16 at 03:51
  • I was thinking more of the `|| [[ ... ]]` stuff – rici Apr 13 '16 at 03:59
  • 1
    The `$'\0'` is not truncated in zsh. And that serves to prove that a `NUL` byte may be used in strings (well, ... , in some strings). –  Apr 13 '16 at 05:31
  • 2
    @BinaryZebra: Good to know about `zsh`, but this answer is about `bash` (the title clearly says `bash`, although the generic tags `sh` and `shell` create ambiguity). I've added a note at the top to clarify, which also contrasts `bash`'s behavior with that of `zsh` and also `ksh`. – mklement0 Apr 13 '16 at 13:28
  • 1
    Fantastic answer. So sad that bash goes with the horrible C zero-terminated string convention. Very ironic that this convention is so inconvenient in many cases... – masterxilo Feb 12 '21 at 08:18
5

It is technically true that the expansion $'\0' will always become the empty string '' (a.k.a. the null string) to the shell (not in zsh). Or, worded the other way around, a $'\0' will never expand to an ascii NUL (or byte with zero value), (again, not in zsh). It should be noted that it is confusing that both names are quite similar: NUL and null.

However, there is an aditional (quite confusing) twist when we talk about read -d ''.

What read see is the value '' (the null string) as the delimiter.

What read does is split the input from stdin on the character $'\0' (yes an actual 0x00).


Expanded answer.

The question in the tittle is:

In a bash script, what would $'\0' evaluate to and why?

That means that we need to explain what $'\0' is expanded to.

What $'\0' is expanded to is very easy: it expands to the null string '' (in most shells, not in zsh).

But the example of use is:

read -r -d $'\0'

That transform the question to: what delimiter character does $'\0' expand to ?

This holds a very confusing twist. To address that correctly, we need to take a full circle tour of when and how a NUL (a byte with zero value or '0x00') is used in shells.

Stream.

We need some NUL to work with. It is possible to generate NUL bytes from shell:

$ echo -e 'ab\0cd' | od -An -vtx1
61 62 00 63 64 0a                           ### That works in bash.

$ printf 'ab\0cd' | od -An -vtx1
61 62 00 63 64                              ### That works in all shells tested.

Variable.

A variable in shell will not store a NUL.

$ printf -v a 'ab\0cd'; printf '%s' "$a" | od -An -vtx1
61 62

The example is meant to be executed in bash as only bash printf has the -v option. But the example is clear to show that a string that contains a NUL will be cut at the NUL. Simple variables will cut the string at the zero byte. As is reasonable to expect if the string is a C string, which must end on a NUL \0. As soon as a NUL is found the string must end.

Command substitution.

A NUL will work differently when used in a command substitution. This code should assign a value to the variable $a and then print it:

$ a=$(printf 'ab\0cd'); printf '%s' "$a" | od -An -vtx1

And it does, but with different results in different shells:

### several shells just ignore (remove)
### a NUL in the value of the expanded command.
/bin/dash       :  61 62 63 64
/bin/sh         :  61 62 63 64
/bin/b43sh      :  61 62 63 64
/bin/bash       :  61 62 63 64
/bin/lksh       :  61 62 63 64
/bin/mksh       :  61 62 63 64

### ksh trims the the value.
/bin/ksh        :  61 62
/bin/ksh93      :  61 62

### zsh sets the var to actually contain the NUL value.
/bin/zsh        :  61 62 00 63 64
/bin/zsh4       :  61 62 00 63 64

It is of special mention that bash (version 4.4) warns about the fact:

/bin/b44sh      :  warning: command substitution: ignored null byte in input
61 62 63 64

In command substitution the zero byte is silently ignored by the shell.
It is very important to understand that that does not happen in zsh.

Now that we have all the pieces about NUL. We may look at what read does.

What read do on NUL delimiter.

That brings us back to the command read -d $'\0':

while read -r -d $'\0' line; do

The $'\0' shoud have been expanded to a byte of value 0x00, but the shell cuts it and it actually becomes ''. That means that both $'\0' and '' are received by read as the same value.

Having said that, it may seem reasonable to write the equivalent construct:

while read -r -d '' line; do

And it is technically correct.

What a delimiter of '' actually does.

There are two sides of this point, one that is the character after the -d option of read, the other one, which is addressed here, is: what character will read use if given a delimiter as -d $'\0'?.

The first side has been answered in detail above.

The second side is very confusing twist as the command read will actually read up to the next byte of value 0x00 (which is what $'\0' represents).

To actually show that that is the case:

#!/bin/bash

# create a test file with some zero bytes.
printf 'ab\0cd\0ef\ngh\n' > tfile

while true ; do
    read -r -d '' line; a=$?
    echo "exit $a"
    if [[ $a == 1 ]]; then
        printf 'last %s\n' "$line"
        break
    else
        printf 'normal %s\n' "$line"
    fi
done <tfile

when executed, the output will be:

$ ./script.sh
exit 0
normal ab
exit 0
normal cd
exit 1
last ef
gh

The first two exit 0 are successfully reads done up to the next "zero byte", and both contain the correct values of ab and cd. The next read is the last one (as there are no more zero bytes) and contains the value $'ef\ngh' (yes, it also contains a new line).

All this goes to show (and prove) that read -d '' actually reads up to the next "zero byte", which is also known by the ascii name NUL and should have been the result of a $'\0' expansion.

In short: we can safely state that read -d '' reads up to the next 0x00 (NUL).

Conclusion:

We must state that a read -d $'\0' will expand to a delimiter of 0x00. Using $'\0' is a better way to transmit to the reader this correct meaning. As a code style thing: I write $'\0' to make my intentions clear.

One, and only one, character used as a delimiter: the byte value of 0x00 (even if in bash it happens to be cut)


Note: Either this commands will print the hex values of the stream.

$ printf 'ab\0cd' | od -An -vtx1
$ printf 'ab\0cd' | xxd -p
$ printf 'ab\0cd' | hexdump -v -e '/1 "%02X "'
61 62 00 63 64
  • 3
    ++ for a much improved rewrite. Re choosing between `$'\0'` and `''` in `bash`: There is no good solution to this problem: the choice is between (a) using `-d $'\0'` to make the `read` command self-documenting, which carries the price of mistakenly suggesting that `$'\0'` creates a NUL, and (b) using `read -d ''` to reflect what's going on _technically_, which carries the price of obfuscating how the `read` command functions. Personally - and it really is a matter of _preference_ - I prefer (b), because the mistaken belief that `$'\0'` creates a NUL can become a problem in many situations. – mklement0 Apr 14 '16 at 12:28
  • 1
    @mklement0 Thanks, it took a while to get it really clean. I have no problem with anyone using `$'\0'` or `''` as long as it is understood that there is no reason to mindless ban or segregate the other possible use. –  Apr 14 '16 at 23:31
1

$'\0' expands the contained escape sequence \0 to the actual characters they represent which is \0 or an empty character in shell.

This is BASH syntax. As per man BASH:

Words of the form $'string' are treated specially. The word expands to string, with backslash-escaped characters replaced as specified by the ANSI C standard. Known backslash escape sequences are also decoded.

Similarly $'\n' expands to a newline and $'\r' will expand to a carriage return.

anubhava
  • 761,203
  • 64
  • 569
  • 643
  • 3
    I... think this is the first time I've *ever* downvoted an anubhava post for inaccuracy. (`$'\0'` does not in fact evaluate to a NUL; it would, if they could be represented in C strings, but they can't). – Charles Duffy Apr 13 '16 at 03:46
  • Completely agree with both of you @CharlesDuffy and mklement0. I have removed inaccurate parts but other answer explains it better. – anubhava Apr 13 '16 at 03:49
  • 1
    @CharlesDuffy NULs are well represented in zsh strings. If we make a simple test inside zsh: `a="$(printf 'ab\0cd')"; echo "$a" | xxd -p` produces `61620063640a`. Yes, a NUL exists in the middle. So: some C created code (well; 66.4% of zsh code anyway) may correctly process NUL containing strings. –  Apr 13 '16 at 05:36
  • 1
    @BinaryZebra, in *bash*, NULs coming from command substitutions are removed. Yes, it's possible to use Pascal strings (which is to say, strings with length metadata stored out-of-band rather than represented with a terminator) in software written in C, but it's extra work (can't use standard-library string-handling calls), and bash (the shell tagged in the question) doesn't do it. – Charles Duffy Apr 13 '16 at 12:38
  • 1
    @BinaryZebra, ...which is to say that by "C strings" I didn't mean "the only kind of string that can be represented in C", but "the kind of string conventionally referred to with 'C Strings' as a term of the art", which happens to also be the only kind of string the C standard library string manipulation functions work with. ("Pascal strings" are, likewise, often used in languages much, much newer than Pascal, but they still have that name). – Charles Duffy Apr 13 '16 at 13:17