5 ms·
I don't like this genre of programming blog post. These things always amount to premature optimization for portability. They point out that some technique that'
by quotemstr 8y ago
I don't like this genre of programming blog post. These things always amount to premature optimization for portability. They point out that some technique that's been used by millions of programs for decades might not work on every single architecture that's technically compatible with the C standard. So what? The techniques work, and because so many programs use these techniques, they'll keep working.
In practice, almost nobody targets esoteric environments. Avoiding useful and well-known tools just for the sake of an environment that will never see your program is just a needless self-imposed tax that's going to suck time from other aspects of development. In my programs, I'll keep hashing uintprt_t values.
- spc476 8y agoWhile an architecture where two distinct pointers could point to the same location is esoteric today (minus `mmap()` tricks), go back 30 years and it was not only esoteric, but downright the most popular system in existence! [1]. Who's to say something just as esoteric becomes the mainstream? (although I hope not---it was horrible). [1] MS-DOS with its FAR pointers.
- anfilt 8y agoHarvard architectures might be an other example that's not really strange. You can have two different pointers with the same value. However, why are we trying to compare data and instruction pointers? They are pointers for different types of data. One being instructions and the other data.
- spc476 8y agoTrue. But C is pretty restrictive in what you can assume. POSIX is more lax (for the programmer, not for the compiler) because it mandates certain behavior---like an all-0 bit pattern for NULL pointers, and the ability to case `void *` to a function pointer (and back again). That "`NULL` need not be physical 0s" [1] is a real pain in ANSI C because `memset(astruct,0,sizeof(astruct))` won't NULL out pointers---you have to explicitly assign NULL to each pointer. It's one of the reasons I tend to stick to POSIX if I can. [1] In source, a 0 in a pointer context is a NULL pointer, but the architecture could mandate "all 1s" as a NULL pointer.
- quotemstr 8y agoThe zero-ness of NULL is a good example of the phenomenon I'm talking about. How much time have people wasted over the years tweaking and worsening code afer somebody pointed out that some platform at one point might not have used the all-zero bit pattern for NULL? In how many cases did the program that was changed get anywhere close to such a strange, special-purpose, and likely obsolete computer? I'm guessing the answer is "vanishingly close to zero." Being exactly ANSI C correct (as opposed to relying on POSIX's stronger guarantees) comes with an engineering cost, and there's no sense paying that cost unnecessarily.
- spc476 8y agoIt's one thing to do something because you found that it works. It's another if you know what the rules are, and why breaking them will work in this case, and if you (or someone else) needs to port the code, you know the potential problem spots that need attention.
- cnvogel 8y agoIt's still non-esoteric today: http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0439b/Behcjiic.html http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.... ARM Cortex M4 supports adressing individual bits (often registers of hardware peripherals) of memory locations as one additional memory location writing to, or reading from a single bit. e.g., from the examples of said infocenter url: *(uint32_t*)0x20000000 |= (1<<7) *(uint32_t*)0x20000000 &= ~(1<<7) should be equivalent to *(uint32_t*)0x2200001C = 1; *(uint32_t*)0x2200001C = 0; Also Analog Sharc DSPs (which, I think, still are being sold with this architecture, and still used, even though I've used them only 10 years ago) alias their memory four times, depending if you want to access it as 16bit, 32bit, 48 or 64bit data.
- Taniwha 8y agoI think you're missing 'volatile's in your casts
- foxhill 8y agowhy would you need that in this case?
- saagarjha 8y agoProbably so the compiler doesn't just optimize out the statements, seeing as they don't seem to have a visible effect on the program execution because they're never read again.
- Taniwha 8y agobecause writing to one location causes the data to change in another (a system register) you don't want the compiler to assume that data in an IO register can be cached in a CPU register
- cnvogel 8y agoThe examples should only view the bit/address mapping, not be a complete example on how to access memory mapped peripherals.
- anfilt 8y agoI agree, but I would not consider hashing pointers a common tool or technique. I would say treating pointers as integers is a more common approach. Heck the STD library has some support for that as well. So any sane compiler for even a wacky environment is going to try to make the transparent.
- saagarjha 8y ago> The techniques work, and because so many programs use these techniques, they'll keep working. So, you’re actively working to keep the language stagnant by encouraging bad practice. Edit: This comment wasn't worded the best way (thanks for reminding me, dang). I'm going to leave the original content up because I don't particularly like deleting things, especially because they are easily retrievable, so hopefully it serves as a nudge to others how not to write comments. Here's what I really meant: By writing nonportable code, you're essentially tying the hands of compiler authors. There are things that are not allowed by the standard that can be reused in the future for adding features, such as using upper bits for tagging. But by doing things like these, you're just creating a self-fulfilling prophecy that things like these won't be changed–but you've really just prevented improvement to the language.
- reacweb 8y agoNo, the bad practice is on the side of standardisation commitees and all users suffer from it. Recently, I got burned by the removal of the symbol CLK_TCK from a header (https://github.com/Orc/pdksh/issues/1 https://github.com/Orc/pdksh/issues/1). If you have access to a RedHat 5, you can observe it with the command /bin/pdksh -c "time sleep 5". I think we should work to replace the C language because all its weaknesses have been worsen by standardisation commitees.
- saagarjha 8y agoI don't quite see how the removal of CLK_TCK has anything to do with "bad practice…on the side of standardization committees".
- reacweb 8y agoThis change breaks working applications, is difficult to notice and has no clear benefits. The same occurs when compilers use standard's undefined behaviour for micro optimizations.
- dang 8y agoThis breaks the HN guidelines, which ask: "Please respond to the strongest plausible interpretation of what someone says, not a weaker one that's easier to criticize." If you'd review https://news.ycombinator.com/newsguidelines.html https://news.ycombinator.com/newsguidelines.html and follow the rules when posting here, we'd appreciate it.
- wutbrodo 8y ago> don't like this genre of programming blog post. These things always amount to premature optimization for portability. They point out that some technique that's been used by millions of programs for decades might not work on every single architecture that's technically compatible with the C standard. So what? The techniques work, and because so many programs use these techniques, they'll keep working. The article lays out its motivation pretty explicitly, and it runs entirely contrary to your point: > My purpose is not to discourage you from casting pointers to integers and using the result. The vast majority of the time this works fine and as you would expect. I just think it’s an interesting part of the language, and C/C++ programmers should be aware of potential the trade-offs. "Details of C implementations are sometimes interesting to think about" is very different from the strawman of "never do this thing because it's not universally portable".