5 ms·
I don't understand how skipping an entry by comparing it with strcmp(name, ".") == 0 turned into name[0] == '.' Is it what really happened (lots of programmers
by kgeist 4y ago
I don't understand how skipping an entry by comparing it with strcmp(name, ".") == 0 turned into name[0] == '.'
Is it what really happened (lots of programmers, by mistake, wrote a comparison function which is just plain wrong), or Rob Pike is conjecturing?
- deleted 4y ago[deleted]
- laurent123456 4y agoHe seems to be saying it was a shortcut, so that the line excludes both "." and ".."
- Retr0id 4y agoThey weren't replacing `strcmp(name, ".")`, they were replacing `strcmp(name, ".") == 0 || strcmp(name, "..") == 0`. It's somewhat easy to see how someone would make this shortcut when programming in C, but they weren't programming in C, they were programming in assembly (as the article describes). It's so much simpler to only check the first char when programming in assembly, so it's easier to see why the shortcut might've been taken.
- alexvoda 4y agoExactly, the logic is that "...", "....", "..*", etc. do not exist and besides users should have the common sense to not name stuff like that. Therefore it is much easier to just use the easier to write (assembler) and much faster solution.
- wizofaus 4y ago"Much" easier? It only needs 3 or 4 extra instructions to check for the null terminator at position 1 or 2 (0 based), which would be an improvement (only 1 or 2 letter filenames starting with dot would be hidden), and a couple of extra to check for dot at position 1. Given all the other things ls has to do, that's negligible.
- alexvoda 4y agoIndeed, but I believe, that is not the mindset of a person programming in an extremely constrained environment. Care for correctness is younger than "ls". For all intents and purposes at the time, it was a hack but it worked, and it worked well.
- wizofaus 4y agoI cut my teeth writing 8086 assembly code where keeping machine code size down to as few bytes as possible was necessary and that still strikes me as very lazy hack - saving a few bytes at the cost of an infinite number of possible filenames being hidden vs just two?
- GekkePrutser 4y agoCare for correctness was much more of a thing, when coding was a rare art and not a copy/paste from stack overflow to finish this week's sprint on time. There was also a lot less code in general so I would expect every line to be considered in much more detail. Also, 'laziness' tends to be a character flaw that manifests itself everywhere in a person's work, not just in one place. And Richie/Kernighan don't exactly have a bad reputation. I wonder if the '-a' parameter of ls appeared at the same time. If so it definitely wasn't an oversight.
- wizofaus 4y agoAre we sure there weren't other rules or conventions in place at the time that specified filenames had to start with an alphanumeric character?
- soegaard 4y agoPike says the code is in assembler - which means it is written by hand. In assembler `name[0]=='.'` is simple to write. Fetch what name points to and compare it to a literal `'.'`. A function call on the other hand requires pushing registers to the stack, pushing the arguments to the stack, call the function, and then restoring the registers. So if you are in a hurry and just want to try something, you will write the equivalent to `name[0]=='.'`.
- samatman 4y agoIt could have checked for ".\0" and "..\0", is the thing. There was no need to bring the whole of strcmp to bear. I think hiding files with a path convention is Good, Actually, but I'm comfortable being in the minority on that, and it's possible that if we instead had a hidden flag a la chmod permissions I would prefer that.
- Findecanor 4y agoI think dotfiles is the best convention I've seen for hidden files. With "hidden" being a file attribute (like on MS-DOS), you'd have the risk of a filename collision with a file that you don't know is there.
- jerf 4y agoAlso, I mean, if you've grown up in the era of multicore gigahertz, where "gigabytes" is where our opening bid on RAM starts, you just don't understand what programming on this era of machine was like. The difference between a single name[0]=='.' and two calls to a string comparison function could very well have resulted in noticeable differences in performance, in real-world cases. I like to keep an eye on the costs of what code I'm writing to make sure I don't get too 21st century and let my codebase bloat until it's slow as molasses, but at the same time I happily harvest the benefits of usually not caring whether this function call is inlined or not, or caring about the exact number of cycles an indirect function call takes, etc. It's a delicate balance but worthwhile to cultivate it.
- slowhand09 4y ago
- czx4f4bd 4y agoRead that part again: > It was in assembler then, but the code in question was equivalent to something like this: > if (name[0] == '.') continue; > This statement was a little shorter than what it should have been, which is > if (strcmp(name, ".") == 0 || strcmp(name, "..") == 0) continue; There's no strcmp() in the first example.
- vitiral 4y agoFor those who don't know, it should have been equivalent to: if (name[0] == '.') { if (name[1] == 0) continue; if (name[1] == '.' && name[2] == 0) continue; }
- zik 4y agoI'm willing to bet it's conjecture. Someone probably said "We need to hide . and .." and then realised "hey, if we need to hide these things we'll probably need to hide other things as well - how about we just hide anything that starts with .?"