On Thu, Aug 25, 2022 at 8:40 AM Alexander Potapenko <glider@xxxxxxxxxx> wrote: > > On Mon, Jul 4, 2022 at 10:07 PM Matthew Wilcox <willy@xxxxxxxxxxxxx> wrote: > > > > ... wait, passing an uninitialised variable to a function *which doesn't > > actually use it* is now UB? What genius came up with that rule? What > > purpose does it serve? > > > > There is a discussion at [1], with Segher pointing out a reason for > this rule [2] and Linus requesting that we should be warning about the > cases where uninitialized variables are passed by value. I think Matthew was actually more wondering how that UB rule came to be. Personally, I pretty much despise *all* cases of "undefined behavior", but "uninitialized argument" across a function call is one of the more understandable ones. For one, it's a static sanity checking issue: if function call arguments can be uninitialized random garbage on the assumption that the callee doesn't necessarily _use_ them, then any static checker is going to be unhappy because it means that it can never assume that incoming arguments have been initialized either. Of course, that's always true for any pointer passing, but hey, at least then it's pretty much explicit. You're passing a pointer to some memory to another function, it's always going to be a bit ambiguous who is supposed to initialize it - the caller or the callee. Because one very important "static checker" is the person reading the code. When I read a function definition, I most definitely have the expectation that the caller has initialized all the arguments. So I actually think that "human static checker" is a really important case. I do not think I'm the only one who expects incomping function arguments to have values. But I think the immediate cause of it on a compiler side was basically things like poison bits. Which are a nice debugging feature, even though (sadly) I don't think they are usually added the for debugging. It's always for some other much more nefarious reason (eg ia64 and speculative loads weren't for "hey, this will help people find bugs", but for "hey, our architecture depends on static scheduling tricks that aren't really valid, so we have to take faults late"). Now, imagine you're a compiler, and you see a random incoming integer argument, and you can't even schedule simple arithmetic expressions on it early because you don't know if the caller initialized it or not, and it might cause some poison bit fault... So you'd most certainly want to know that all incoming arguments are actually valid, because otherwise you can't do even some really simple and obvious optimziations. Of course, on normal architectures, this only ever happens with FP values, and it's often hard to trigger there too. But you most definitely *could* see it. I personally was actually surprised compilers didn't warn for "you are using an uninitialized value" for a function call argument, because I mentally consider function call arguments to *be* a use of a value. Except when the function is inlined, and then it's all different - the call itself goes away, and I *expect* the compiler to DTRT and not "use" the argument except when it's used inside the inlined function. Because hey, that's literally the whole point of inlining, and it makes the "static checking" problem go away at least for a compiler. Linus