6 ms·
I miss the good old times where a pointer was just a number, and if you did `*addr` you plainly read from that memory address. I'm not sure if the standard was
by captainmuon 8y ago
I miss the good old times where a pointer was just a number, and if you did `*addr` you plainly read from that memory address. I'm not sure if the standard was ever that way, but compilers sure used to behave like that.
Maybe we can one day get a `--std=simple-world` flag that forgoes a few optimizations and makes UB code do the "obvious" thing.
- api 8y agoIt never was guaranteed by any standard, and in fact numerous old machines had weird pointer formats: segmented addressing, strange widths (36 bits), and tagged pointers come to mind. Its more like we had this window of time when pointers were not weird and got too used to it.
- captainmuon 8y agoSure, but back then the standard was not relevant. You had your x86 computer, your compiler (MSVC, DJGPP, CodeWarrior, Borland...) and maybe a "how to write C/C++" book. You did have weird things like segmented addressing, but for most purposes, pointers were just memory addresses, and you could use casts to reinterpret data as you wished. In fact, using bit-cast-magic and doing pointer arithmetics were the preferred way of doing things. It's strange that we put so much effort into learning all this arcane knowledge and now we're supposed to unlearn it...
- wruza 8y agoI can’t tell for sure, since I was too young back then and didn’t write something complex enough, but I suspect that compilers were not evil genies back then. It was probably later gcc who first used UB as an excuse to evil optimizations. I also don’t understand a reason behind dragging all that legacy into current standards. Does a real application of it make at least 0.1% of all usage? You cannot even buy a chip that implements segments, tagged pointers, etc etc. at least they could make a special mode where you can span across symbol whatever it means or see a pointer as a cpu sees it. All this can be solved with simple ptr_untag(p), ptr_span(expr) and similar constructs, but instead we have resort to outsmarting the specific compiler logic or introducing ourself with complicated type systems. That went insane. Personally I just want my bytes in linear address space and a way to tell which bytes point to which and which do not. I liked asm and then C, they were two of my first three languages, but what C became today is just a horrible mess.
- ChrisSD 8y agoBut memory isn't a linear address space. If you're forced to treat memory as strictly linear than you're denied many optimizations.
- twtw 8y ago> But memory isn't a linear address space Would you mind expanding on this point a bit?
- wruza 8y agoI think it was mostly aliasing-related, and that’s why I mentioned “tell which bytes point at which”. Managing C today is like managing that girlfriend who doesn’t say anything straight and avoids direct conversations. I’m not against optimizations, I’m against compiler pretending to be smarter than average me and spoiling our relationship when I only have basic demands. If not that, I’m also curious.
- Too 8y agoSorry but it's the other way around. You are the one pretending to be smarter than the compiler by imagining objects are laid out sequentially in an infinite char[] when they they are in fact just abstract objects laid out in whichever way the compiler thinks is best. Just keep it this way and it will be much easier to manage C, it doesn't need micro management and neither does girlfriends.
- wruza 8y agoI'm saying that I don't like this model, not that I want to see everything as char[] in it. You insist that I should just embrace the model, since char[] doesn't work in it. I know, ok? If that tauthology was an argument, it completely missed the point. Below the compiler, I'm pretty familiar how things are laid out, since there is ABI, packing/alignment rules, documented hardware and 15 years of dealing with them. Please don't mock up magic and wisdom out of few conventions.
- pjmlp 8y agoWhen I was writing portable UNIX software in the late 90's, early 2000's, the standard was quite relevant.
- mcguire 8y agoAll the world's a VAX.
- TimJYoung 8y agoIt's still that way with Object Pascal (Lazarus/FreePascal and Delphi). You can do all of the things mentioned in the blog post without the compiler screwing you by trying to interpret what you're doing with the pointer arithmetic/access. You still get really good performance, so I'm not sure why the compiler developers feel the need to go this deep into optimization territory on what amounts to "one step above assembly" code. If a developer is doing pointer arithmetic, then the compiler should step back and let them perform any necessary optimizations themselves because they're already working at that level.
- pcwalton 8y agoThen all software would get slower for no reason other than making compiler nerds happy. C++ in particular heavily depends on optimizations like SROA, which you just killed in most cases (e.g. whenever you called a method on an object, the compiler would be forbidden from promoting its contents to registers because of the "this" pointer). That would be doing a huge disservice to users, virtually all of whom don't know or care one bit about what machine instruction the "*" operator in C++ corresponds to.
- captainmuon 8y agoWell, not all software, only where you'd decide to use that feature. In non performance-critical code, I'd disable certain optimizations anyway to make sure that sanity checks do not get optimized away. (The Linux kernel had a few high-profile cases of this problem.) One way to implement my idea would be as pragmas that tell the compiler "don't optimize away this null check", "assume this variable can alias", "just emit the obvious ASM for memory access" or "put memory barriers around this code". I don't see how this kind of "stupid memory access" would make e.g. SROA impossible. If I just access the memory around "this", sure, I would not see the layout I'd naively expect. But that's not what I want anyway. I want to see the memory as it is actually laid out.
- saagarjha 8y agoThere are ways of informing the compiler of your intentions; using idioms such as memcpy, for example. The compiler will peer through the function call and generate the code you want.