4 ms·
Standard Forth, to my knowledge, doesn't have UB and consequently doesn't allow the optimization. That'd just be : foo CELL + 20 SWAP ! ; there. Machine l
by remexre 3y ago
Standard Forth, to my knowledge, doesn't have UB and consequently doesn't allow the optimization. That'd just be
: foo CELL + 20 SWAP ! ;
there. Machine languages also generally don't have this kind of UB, and don't allow the optimization.
It's not impossible to imagine a C without UB, it's just not a particularly desirable language.
- Jtsummers 3y agoThe UB permits the optimization, but is not necessary for it. If a language had a stricter definition of pointer and memory access behavior then the optimization would still be applicable if it conformed to the assumption that people are making around the UB in C. UB is not necessary for optimization, it just permits some optimizations which may or may not be valid and may or may not be consistent across compilers and platforms because people get to fill in the gaps with whatever they want.
- Dylan16807 3y agoParameters don't really work the same way in Forth. A similar C program would explicitly pass in an entire stack every time it runs a function, or have a global stack variable. And such a C program would disallow the optimization whether or not you consider UB. Machine language means you have basically no rules imposed on your code at all. So it's true that you can't optimize anything, but I think that's outside the scope of normal language talk.
- remexre 3y agoIn my example, the variables are assumed to be addressable, only the address of x was passed via the stack. Dunno what you mean about having no rules imposed on your code -- you can define the semantics of the language formally and execute them on a machine, same as you can for C, JavaScript, or Prolog.
- Dylan16807 3y ago> In my example, the variables are assumed to be addressable, only the address of x was passed via the stack. Yeah but I could add 3 billion to the pointer instead. Now what happens, if we're trying to define behavior? > you can define the semantics of the language formally If the semantics aren't a direct translation into CPU opcodes, then it's not machine code. And CPU opcodes can access all memory at all times including self-inspection so you can't change anything for optimization purposes without an additional framework on top.
- remexre 3y ago> Now what happens, if we're trying to define behavior? The cell whose address is three billion greater, mod the size of the address space, now has a value of 20? > If the semantics aren't a direct translation into CPU opcodes, then it's not machine code. Just because the semantics are defined that way doesn't necessarily mean you couldn't make another implementation that obeys those semantics. For instance, QEMU can perform optimizations on the code it runs, and invalidate them if the program changes those instructions. The semantics of reading from and writing to memory are unchanged by these optimizations, and the implementation doesn't need to do anything special on read.
- Dylan16807 3y ago> The cell whose address is three billion greater, mod the size of the address space, now has a value of 20? Cool. It sounds like you figured out a restricted form of pointers for stack variables, since there's no danger of corrupting the code or breaking important invariants elsewhere. Now imaging tightening those restrictions a bit. Instead of wrapping pointers inside the entire stack, wrap/constrict pointers inside their original variable. Now you have a language with no UB that allows the optimizer to replace y with 42! TL;DR: If you let pointers go hog-wild, your language has UB even before you consider optimizing. You don't need to add UB to allow optimizations. If you don't let pointers go hog-wild, in a language without UB, then you can enhance those restrictions to allow the y->42 optimization while still not having UB. > For instance, QEMU can perform optimizations on the code it runs, and invalidate them if the program changes those instructions. The machine can take shortcuts, and when QEMU is acting as a virtual machine it can do that. But the compiler can't take any shortcuts, because it never knows when external code is going to examine random bytes and need them to be unchanged.