5 ms·
Initialization is not the same thing, though, for everything but Ada. I'm not looking for a c-like language where variables must be defined / are implicitly in
by TheLoneWolfling 12y ago
Initialization is not the same thing, though, for everything but Ada.
I'm not looking for a c-like language where variables must be defined / are implicitly initialized to a constant. Those have problems, among other things the cost of double-initialization.
I'm looking for a c-like language where the compiler is free to assume that an uninitialized variable is anything it wants - but it must be consistent about it. So, for example, "return x - x", where x is an integer, will always return zero.
- masklinn 12y ago> Those have problems, among other things the cost of double-initialization. Compilers optimise away significantly more complex things than initialising a variable twice. > I'm looking for a c-like language where the compiler is free to assume that an uninitialized variable is anything it wants - but it must be consistent about it. So, for example, "return x - x", where x is an integer, will always return zero. So you're looking for C? Because whatever garbage's in there will be the same garbage in both references to x. I have issues with your qualification of that as "sane" though.
- TheLoneWolfling 12y agoDid you read the article? In C, the compiler is perfectly allowed to compile "return x - x" with x uninitialized into "return 1". Accessing an uninitialized variable in C is undefined behavior. The compiler can do anything. Nasal daemons. > Compilers optimise away significantly more complex things than initialising a variable twice. Right, but there are cases where being required to initialize a variable to, say, 0, is not equivalent than being required to initialize a variable to <some arbitrary value>. For instance, "if (x == 0) y = someExpensiveFunction();" with x being uninitialized. With the "must be initialized to a specific constant" this sort of thing cannot be optimized, whereas with "must be consistent" this can be compiled down to nothing.
- deleted 12y ago[deleted]
- masklinn 12y ago> Did you read the article? Of course. > In C, the compiler is perfectly allowed to compile "return x - x" with x uninitialized into "return 1". Accessing an uninitialized variable in C is undefined behavior. The compiler can do anything. Sure. The peephole optimiser will pretty certainly run first and remove the whole expression though. > For instance, "if (x == 0) y = someExpensiveFunction();" with x being uninitialized. With the "must be initialized to a specific constant" this sort of thing cannot be optimized, whereas with "must be consistent" this can be compiled down to nothing. You've noted yourself in an other comment that the arbitrary value may be 0, the compiler can make no assumption about what's inside x, so there's absolutely no way to optimise this away, whereas with a specified constant the compiler knows statically whether the test will or will not succeed.
- TheLoneWolfling 12y ago> The peephole optimiser will pretty certainly run first That's what I'm trying to avoid though. The whole "pretty certainly" thing. The compiler will "pretty certainly" do not optimize this. The compiler will "pretty certainly" optimize that. And then compiler versions change and people get bitten. Time and time again. You're misinterpreting what I'm trying to say w.r.t. uninitialized variables here, or perhaps I'm just being idiotic at explaining myself. In what I'm describing, the compiler can assume the value of x to be anything it wishes. It's just that, once the value is fixed, it must be fixed. Think of it this way: the compiler may choose any initial value of any variable it chooses. I'm proposing a language where a read from an uninitialized variable must be consistent with the uninitialized variable having been set to an arbitrary value (in range) before the first read from it. So compiling the static code {int x; return x;} into {return 0;} is perfectly allowed, as is compiling it into {return 42;}.
- Dylan16807 12y ago>The peephole optimiser will pretty certainly run first and remove the whole expression though. Which is pretty dangerous. RunCriticalCodeA(); if (x) { y = 3; RunCriticalCodeB(); } else { y = 4; RunCriticalCodeB(); } OtherCriticalCodeC(); Fail to initialize x and suddenly all that code is replaced with a return. Even the part outside the if, even the part before the if. Compilers already exist that are this aggressive.
- xamuel 12y agoI'm happy to say your question led me on a very interesting adventure :) Suppose x is an uninitialized int★ (pretend ★ is an asterisk---HN doesn't seem to allow asterisks in comments). Suppose we do int ★y = x; (★x)++; (★x)--; Should y-x necessarily be 0, in the language you're looking for? Think carefully. If x had been initialized (and pointed to a valid memory location, say), would y-x necessarily be 0? Surprisingly the answer is no! It's possible that x could point to itself. In that case, (★x)++; actually changes the value of x itself, so that it is no longer cancelled out by the following (★x)--; I guess the moral is that what you're asking for is subtler than meets the eye
- anon4 12y agoIt would be sane to ask that the literal expression "x - x" be optimised to 0, but I would never dream of asking that "y - x" be optimised to 0. Not unless the compiler can prove the values will be exactly the same in all circumstances and no, it's not allowed to just delete code that invokes undefined behaviour.
- pascal_cuoq 12y ago> no, it's not allowed to just delete code that invokes undefined behaviour. I think it is.
- cbd1984 12y ago> it's not allowed to just delete code that invokes undefined behaviour. In your mind, what does 'undefined behavior' mean? Because to the rest of us, it means "The standard says the compiler can do anything at all".
- TheLoneWolfling 12y agoI think he's also talking about my mythical C-like language that has somewhat sane rules for these things.
- cbd1984 12y ago
- WalterBright 12y ago> Those have problems, among other things the cost of double-initialization. In D: int x; // initialization eliminated as a 'dead store' by optimizer x = 3; You can also do: int x = void; making the "don't initialize this" proactively marked, rather than being the default behavior.
- TheLoneWolfling 12y agoRight, and in trivial cases that works. But if you've got, for example int x; if (somethingThatYouKnowIsTrueButTheCompilerDoesnt()) x = 3; there's no way to express that with either of those methods. You'll end up with the redundant store.
- WalterBright 12y agoIf you know it is always true, why is it in an if() ? You'd right it as: int x; if (somethingThatYouKnowIsTrueButTheCompilerDoesnt()) x = 3; else assert(0); and the compiler will remove the redundant store to x.