6 ms·
I have seen it claimed that null-terminated strings were encouraged by the instruction sets of the time -- that some instruction sets make null-terminated seque
by holmak 11y ago
I have seen it claimed that null-terminated strings were encouraged by the instruction sets of the time -- that some instruction sets make null-terminated sequences easier to handle than length-prefixed ones. The article's error-message-printing code snippet is a good example. Does anyone think there is any truth to this?
- HillRat 11y agoThe ASCIZ directive on the PDP-11 assembler took a string literal and blitted it to memory with a trailing NULL, so there was a convenience factor there. BCPL and B used null-terminated strings, so it made sense for C to inherit the practice. Pascal strings were significantly size-limited due to memory constraints (an implementation detail), so there was a reason to prefer null termination, but in essence we're still slaves to an obsolete instruction set.
- coliveira 11y agoMaybe that's not the whole picture, but I think a big reason for null terminated strings is that C has pointers. A char pointer makes it practical to move through strings and a NULL terminator is easier to handle than a size test. In the end, sized strings make C code more complicated, unlike other languages such as Pascal.
- pjmlp 11y agoWhich also has pointers, yet makes use of safe strings.
- coliveira 11y agoTrue, I should have said pointers and pointer arithmetic. In Pascal you cannot do these things because there is no pointer arithmetic to move along strings and arrays.
- pjmlp 11y agoOnly if you are speaking about the boring ISO Pascal. All Pascal dialects like Apple Pascal and Turbo Pascal had pointer arithmetic.
- coliveira 11y agoThat was an extension to the Pascal language, it doesn't really change the way to write idiomatic code.
- pjmlp 11y agoMoving goal posts are we? Should I list all the compiler specific features that everyday C programmer uses but aren't defined in ANSI C, e.g. inline assembly? No professional Pascal compiler was a pure ISO Pascal, that error was left for schools teaching bad Pascal. Professional Pascal compilers were way more powerful than C, safer and in the days of K&R C chaos, just as portable.
- coliveira 11y agoI have made no comment about the quality of Pascal vs. C. In fact I like Pascal a lot, my comment is just on the way to write idiomatic code in each language. In C it is much easier and common to traverse data structures. Pascal may do it in some implementations, but its not how programmers used to organize their code. This just means that for C programmers it is frequently easier to work with NULL terminated strings.
- jamesbowman 11y agoYes, the PDP-11 instruction set makes null-terminated strings especially efficient. Strcpy() is 3 instructions per character, for example. The PDP-11 features that make this possible are (1) post increment addressing and (2) MOVE instructions set the condition codes.
- toast0 11y agoNull terminated is going to be nice in most instruction sets, you don't need to keep track of a count, so you save a register, and you have one less thing to increment (or decrement). Loop condition is basically free too, loading the next byte into a register is going to set the status register, so you don't need a compare, you can just branch if the zero flag is set. As long as you are handling good data, it's clearly more efficient.
- rasz_pl 11y ago> loading the next byte into a register is going to set the status register not in x86
- toast0 11y agoIf you load into C, you can JCXZ, instead of JZ, since you don't get the zero flag for free with a load.
- Zardoz84 11y agoAlso, null-terminated arrays are used for other stuff that not are strings. For example : https://developer.gnome.org/glib/stable/glib-String-Utility-Functions.html#g-strsplit https://developer.gnome.org/glib/stable/glib-String-Utility-... returns an null terminated array of strings.
- Buge 11y agoargv is a null-terminated array of string.
- ksherlock 11y agoAside from the Zero flag, there was also a Negative/Signed flag. Setting the high-bit in the last character (or clearing it if the rest had the high bit set) was also a way to terminate strings and save a byte over null-terminated strings. People who go ape-shit over 0-terminated strings would probably be even more upset if we still did that.
- SCHiM 11y agoYes, the architecture on which you're most likely reading this (x86 or x64) also has semi-dedicated string handling instructions, akin to higher level string functions. For example, a string copy 'instruction' that copies a 0 terminated string from one location to another looks like this: lea esi, source_string lea edi, dest_string repnz movsb ; copies esi -> edi until *esi = 0
- rasz_pl 11y agoare you sure about that? http://docs.huihoo.com/help-pc/asm-repne.html http://docs.huihoo.com/help-pc/asm-repne.html http://faydoc.tripod.com/cpu/repnz.htm http://faydoc.tripod.com/cpu/repnz.htm repnz movsb is undocumented and undefined, MOVS doesnt modify flags, not sure how would that work
- SCHiM 11y agoWhoops, looks like I've indeed mixed up my assembler. While the rep/repe/repnz can be used in conjunction with movs(b/w) it will not terminate on the z flag in the eflags register (so it won't stop if *esi == 0) but rather when ecx = 0. So ecx needs to contain the size of the string you want to move, and rep movsb does not use the zero flag.