In typical Unix fashion, however, it is designed to use internal, global state, so you can only have one table at a time.
There is a GNU extension that provides the same functions with an `_r` suffix that allow you to work with more than one table.
In typical Unix fashion, however, it is designed to use internal, global state, so you can only have one table at a time.
There is a GNU extension that provides the same functions with an `_r` suffix that allow you to work with more than one table.
https://en.cppreference.com/w/c/string/byte/strtok
Was there some reason it was optimal to write these functions this way back in the early days of Unix?
As long as you don't have multiple threads (and you shouldn't, and on Unix you couldn't) the static-variable interface in these cases was usually more convenient, though more bug-prone.
There's also a micro-efficiency question.
Global variables are at a known memory address. If you put them in a struct and pass around a pointer to it, they are at a dynamically computed memory address. Every time you want to access them, you have to add the field offset to the struct's base pointer. This is a small amount of extra computation, and how much it actually costs you depends on the hardware—on the 8080 it's a mess that probably requires you to spill a couple of registers onto the stack, and on modern implementations of amd64 like the ones from Intel, it probably takes literally zero extra time, because you probably aren't keeping all of your addition-capable functional units busy anyway.
I don't know the PDP-11's instruction set well enough to say, but I suspect the cost of such indexed addressing was intermediate between these extremes: much like the 8086, it had an "index" addressing mode, mode 6, which added an immediate 16-bit offset to a base register https://pages.cpsc.ucalgary.ca/~dsb/PDP11/AddrModes.html, and it doesn't seem to have had a pure immediate addressing mode where the address of the variable is just an immediate word without any indexing. But if you didn't need a base register for your variables, you could use PC-relative addressing, thus saving a register and decreasing register pressure (the PDP-11 only had 8 general-purpose registers, and one of them was PC, so it really only had 7).
I don't have any idea what actual PDP-11 compilers did, though, and that matters a lot here.
Plus you weren't going to need more than one anyway, your program wasn't going to be big enough.
https://github.com/ludocode/pottery/tree/master/examples/pot...
Be warned, hsearch is terrible. You should probably only use this if you have some existing code that depends on hsearch and you want to make it portable.