Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

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?


Null 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.


Also, null-terminated arrays are used for other stuff that not are strings. For example : https://developer.gnome.org/glib/stable/glib-String-Utility-... returns an null terminated array of strings.


argv is a null-terminated array of string.


> loading the next byte into a register is going to set the status register

not in x86


If you load into C, you can JCXZ, instead of JZ, since you don't get the zero flag for free with a load.


Aside 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.


Yes, 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.


The 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.


Yes, 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


are you sure about that? http://docs.huihoo.com/help-pc/asm-repne.html http://faydoc.tripod.com/cpu/repnz.htm

repnz movsb is undocumented and undefined, MOVS doesnt modify flags, not sure how would that work


Whoops, 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.


Maybe 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.


Which also has pointers, yet makes use of safe strings.


True, 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.


Only if you are speaking about the boring ISO Pascal.

All Pascal dialects like Apple Pascal and Turbo Pascal had pointer arithmetic.


That was an extension to the Pascal language, it doesn't really change the way to write idiomatic code.


Moving 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.


I 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.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: