3 ms·
the dereference itself is UB My point was the dereference itself could be a valid dereference depending on architecture. You can have a pointer to address 0 or
by shultays 2y ago
the dereference itself is UB
My point was the dereference itself could be a valid dereference depending on architecture. You can have a pointer to address 0 or 42 or whatever and it all depends on what is mapped to that address. Could be ram, could be some other hardware etc
I guess I was nitpicking. For gcc and the target architecture that is compiling that code it is UB so it is optimizing things with that information
Does "A pointer whose value null" always means that it is literally value 0? That is how it is in practice but how C++ handles architectures where 0 is a valid address that a program can dereference? Does cpp compilers use another value for nullptr in such architectures?
- int_19h 2y agoIt is UB for any C compiler and for any architecture because the language defines it as such. However, because it is UB, the compiler doesn't need to do anything special if there's no trap on null dereference, since "reading something" is a perfectly valid subset of UB. The only thing that it needs to ensure is that no global, local, or heap-allocated C object can end up at address 0, which is easily done by "wasting" a single word at that address (or using it for some internal purposes). It may still be that there is something useful at address 0 that some code may want to access. For example, in real-mode x86, the interrupt vector table starts at that address, so if you want to change what gets called to handle INT 0h, you'd need to write into it. But at this point you're already deep into architecture-specific stuff, and so it's not unreasonable to expect you to use some special facilities that a compiler for this architecture might provide to enable it, instead of the usual pointer dereference.
- shultays 2y agoI am a bit confused, in another post you mentioned The C spec only requires that integer constant expressions that have zero value are nullptrs. The moment you assign it to an int variable, it's no longer a constant expression as far as the language is concerned, so if you then cast that int variable to a pointer, the result is indeterminate It is not an integer constant that gets assigned to a pointer so this is not a null pointer in that case? It is just a pointer with address of 0 (which very well might be the implementation of nullptr but from my understanding that is not required?) so shouldn't nullptr dereferencing rule not apply here?
- int_19h 2y agoIndeed, it's UB not because it's dereferencing a nullptr; it's UB because it's dereferencing an invalid pointer (i.e. a pointer that does not point to any C object). An implementation could declare that there is a valid object at address 0, I suppose, but strictly conforming code cannot rely on this. As far as I remember, the only ints you can cast to a pointer and then safely use are those that were cast from (valid) pointers in the first place.
- compiler-guy 2y ago> For gcc and the target architecture that is compiling that code it is UB so it is optimizing things with that information For every C and C++ standards compliant compiler it is UB. Every single one. By definition, whether or not the compiler then takes advantage of that. It may or may not be legal on the target machine in question, but C and C++ don't target the machine in question, they target an abstract machine with certain properties. The behavior of the abstract machine is then translated to behavior on the target machine. Dereferencing the nullptr on the abstract machine can result in any behavior at all, including what you describe here, but it is not promised by the standard. If you want to access memory at address zero, you cannot do it in a defined way from within the language. You can drop to assembly or use compiler-defined extensions, but if you don't do it like that, you are playing with UB.