6 ms·
> pointer provenance, inability to read uninitialized memory what do you mean by these two? not sure about the former. as for the latter, of course you can re
by radarsat1 7y ago
> pointer provenance, inability to read uninitialized memory
what do you mean by these two?
not sure about the former. as for the latter, of course you can read uninitialized memory, unless you mean something else?
- umanwizard 7y agoNo, reading uninitialized memory in C is UB.
- tspiteri 7y agoAs far as I know (and I could be wrong), reading uninitialized memory in C is not UB, but gives an indeterminate value, which may be either an unspecified value or a trap representation. If it is a trap representation, accessing it is indeed UB, but if all possible values of your memory are valid, e.g. if you have an unpadded integer where every bit representation means something valid, then it is not UB, though it is still an unspecified value which does not even have to be consistent: you could get different values when reading the same uninitialized location twice. Edit: Some excerpts from the C standard: 6.7.8 Initialization 10 If an object that has automatic storage duration is not initialized explicitly, its value is indeterminate. 3.17.2 indeterminate value either an unspecified value or a trap representation 3.17.3 unspecified value valid value of the relevant type where this International Standard imposes no requirements on which value is chosen in any instance 6.2.6 Representation of types 6.2.6.1 General 5 Certain object representations need not represent a value of the object type. … Such a representation is called a trap representation.
- lmkg 7y agoNot a C expert, just reading what I can find online: This page says value is indeterminate, which is either unspecified or a trap, as you say: https://wiki.sei.cmu.edu/confluence/display/c/EXP33-C.+Do+not+read+uninitialized+memory https://wiki.sei.cmu.edu/confluence/display/c/EXP33-C.+Do+no... But. This part says that reading an indeterminate value is, in fact, undefined behavior (line 11 in the table): https://wiki.sei.cmu.edu/confluence/display/c/CC.+Undefined+Behavior#CC.UndefinedBehavior-ub_11 https://wiki.sei.cmu.edu/confluence/display/c/CC.+Undefined+...
- tspiteri 7y agoThat says used, not read. And indeterminate, not unspecified. My point was on reading a value, not on acting on the value. I know it looks like nit-picking, and you should just not read uninitialized memory, but I don't think it's consistent with the standard to say that reading uninitialized memory is always UB.
- lmm 7y agoWhat kind of read would not constitute "using" a value? And per your previous post an object that was not initialised is indeterminate, not just unspecified. So yes, reading uninitialized memory is always UB.
- deleted 7y ago[deleted]
- deleted 7y ago[deleted]
- madmax96 7y agoA read into a character type. From 6.2.6.1¶5: >Certain object representations need not represent a value of the object type. If the stored value of an object has such a representation and is read by an lvalue expression that does not have character type, the behavior is undefined. ... Such a representation is called a trap representation. A read from uninitialized memory is not always UB.
- lmm 7y agoWhat you quoted doesn't actually say anything about what happens when a trap representation is read into a character type. Such a read is still "using" the value at least in the everyday sense of the word, so in the absence of something explicitly to the contrary, as far as I can see the part of the standard that states that using an uninitialised value is UB stil applies. Per http://www.open-std.org/jtc1/sc22/wg14/www/docs/dr_451.htm http://www.open-std.org/jtc1/sc22/wg14/www/docs/dr_451.htm , the current standard is unclear in some respects, but the latest committee view is that that under the current standard any library function (including memcpy) may exhibit undefined behaviour when called with uninitialized memory, even when the uninitialized memory is of character type or is propagated through values of character type.
- dooglius 7y agoThat's the way I think it _should_ work, but sadly does not. For instance, see https://godbolt.org/z/ent-xp https://godbolt.org/z/ent-xp
- tspiteri 7y agoYour code is int x; if(x == 0) foo(); if(x != 0) foo(); That is reading the uninitialized value twice. Since it is unspecified, it does not have to be consistent, so you could get the same behavior as non-zero for the first reading, and zero for the second reading. Changing your code to: int x; if(x == 0) foo(); else foo(); will give different output (same if you use !=).
- ncmncm 7y agoA good optimizing compiler will just elide the whole code block.
- tspiteri 7y agoOnly if there was UB, and the point is that there probably isn't. (I'm not really knowledgeable on the C standard, so I might have misinterpreted something.)
- ncmncm 7y agoMaking an "if" statement depend on the value of the uninitialized memory is an example of what is meant by using the value, and thus UB. In the compiler discovers UB, the Standard places no requirements of any kind on the program or compiler. It is free to launch missiles, or (more likely) assume this code cannot be reached, and omit it from the program, along with any code that reaches it unconditionally, and any check that would send control that way. Such elision is the basis for many important optimizations. Implementations are free to define things left undefined by Standards. For example, "#include <unistd.h>" is UB by the ISO Standard, but defined by Posix, which implementations also adhere to.
- 7y ago
- umanwizard 7y agoThanks, it seems you are right. Sorry that you got downvoted whereas my wrong statement got upvoted; such is the nature of HN.
- eternalban 7y agoNo. It is not "undefined behavior". The "behavior" here is assignment (reading memory). It always will behave precisely and consistently: it _will_ assign the "indeterminite" value of the un-initialized memory. Using such an "indeterminite value" in other operations (e.g comparison per the link Steve B. posted above: https://www.ralfj.de/blog/2019/07/14/uninit.html https://www.ralfj.de/blog/2019/07/14/uninit.html) is the UB bit.
- throwaway_pdp09 7y ago> [reading memory} always will behave precisely and consistently What is the point of not making it UB? You can't AFAICS possibly rely on any useful way on it behaving 'precisely and consistently' so just make it UB anyway?
- saagarjha 7y agoI think this lets you copy it around, e.g. when you have a struct that you have partially initialized.
- throwaway_pdp09 7y agoThat makes sense, finally. Thanks.
- chrisseaton 7y agoCan you write a well-defined C program that reads uninitialised memory?
- dooglius 7y agoNot portably, you could of course use inline assembly in practice, but the normal way of doing it is UB.
- BenjiWiebe 7y agoWouldn't this do it? int a; printf("%d", (&a + sizeof(int)));
- chrisseaton 7y ago...but that isn't a well-defined program, is it?
- saagarjha 7y agoReads? I think so; I believe the bad part is when you try to use it.
- chrisseaton 7y agoNo, it is undefined behaviour. Check the spec.
- saagarjha 7y agoI couldn't find the verbiage for that. The standard seems to have this under undefined behavior: > The value of an object with automatic storage duration is used while it is indeterminate. But reading the value without using it seems fine?
- chrisseaton 7y agoThe 'object' in this context is the storage location, not the value you read from it. You're 'using' the 'object' when you read from it.
- steveklabnik 7y agoFor the first, https://blog.regehr.org/archives/1621 https://blog.regehr.org/archives/1621 For the second, https://www.ralfj.de/blog/2019/07/14/uninit.html https://www.ralfj.de/blog/2019/07/14/uninit.html (the second one is a bit more Rust focused but the core idea is the same)
- deleted 7y ago[deleted]