Earlier quoted context omitted.
If it is defined as an error, but the compiled build will continue to run with the value wrapped around, I would say that's indistinguishable from UB.
It's indistinguishable from unspecified behavior, not from undefined behavior. Unspecified behavior has to pick from a finite list of allowed behaviors. Undefined behavior can do anything .
Everything in C is undefined behavior
631–640 of 748 posts
Re: Everything in C is undefined behavior
#632Earlier quoted context omitted.
Where is the part about unaligned pointers?
Strings typically consist of UTF-8 bytes, and any old `char*` pair has no alignment guarantees.
Re: Everything in C is undefined behavior
#633The problem is incorrectly assuming that the spec is meaningful in some kind of rigorous way. It’s not. All that matters is what C compilers actually do and what real C programs expect. This is a good thing. It creates a culture where the two sides meet each other where they’re at
We also have a very limited number of compilers and a small number of prevalent architectures today. As long as you know the behavior of the target compiler and architecture, the behavior is defined, it's just not specified.
But why I’m saying has always been true. What has changed is that the effective portability of C and C++ code has increased due to the reduction in number of compilers and arches
Re: Everything in C is undefined behavior
#634Earlier quoted context omitted.
Edit: I think one part of the confusion is we were addressing different parts of the first example of the article. You were referencing the int foo(..) snippet (which I agree has no UB), but I was referencing the parse_packet() snippet (which has UB by construction), which was also part of the first example :). You are beginning to understand. Yes, surprisingly, it is (1) that is being claimed. The mere expression is…
Thanks, yes I think we had some confusion on the foo() vs parse() and I was referring to foo(). But even for the parse() example, the issue is the aliasing rules (and not the alignment - though that could still be an issue depending on input!) Aliasing isn't even mentioned in the article. Instead the example presents this thing 'people do all the time' and identifies it 'UB' without even identifying the actual issue.…
One thing though, for parse() not only is it violating strict aliasing, it is also indeed violating alignment requirements.
To quote the standard again:
> 6.3.2.3. 755 If the resulting pointer is not correctly aligned for the pointed-to type, the behavior is undefined.
Re: Everything in C is undefined behavior
#635Earlier quoted context omitted.
Of course it's optional (although I didn't mean to imply that). Even using computers at all is optional. I never said that I don't aim to follow the standard, have a clean compiling program without warnings and without UB, etc. I do strive to achieve all of that. But it's not entirely black and white, either. In practice I'm fine accepting that some bugs are technically UB but whatever, we've found a bug by whatever…
In practice, GCC -O2 will happily erase entire swathes of code and turn perfectly logical source into nonsense assembly whenever it gets as much as a sniff of UB anywhere in the code path. Nobody would be talking about UB if GCC wasn't so aggressive in abusing the freedom UB gives. To paraphrase your earlier comment - you lose low-friction polymorphism (unpredictable compiler output causes a lot of friction). You los…
On the other hand, what I've observed with my own eyes is interesting phenomenons like performance drops, e.g. memory bandwidth dropping from gigabytes/sec to 300 KB/sec due to false sharing on an ARM SOC for example.
Re: Everything in C is undefined behavior
#636Earlier quoted context omitted.
> I’ve never felt that pointer reads or writes were lacking descriptiveness here. I would argue the only surprising thing is that they might be optimized out The C and C++ languages would be very slow by modern standards if you insist that reading or writing via a pointer must result in immediate fetches or stores to memory. > Volatile on a non pointer value is not for MMIO, though, that’s typically for concurrency l…
> You're holding it wrong. Perhaps you've been holding it wrong for so long and so confidently that you've distorted the world around you -- indeed on MSVC on x86 or x86-64 that actually happened -- but, you're still holding it wrong. Please explain. How would you make the variable backed by a hardware register region? Is this using some sort of linker trick to change where the value lives in memory?
Microsoft's platform was x86 only for years, and because Intel's design pays for a lot more memory ordering by default than most, on Microsoft's platforms just "volatile" would kinda work even though it was the wrong thing, so Microsoft explicitly grandfathered this for x86 and x86-64 only, you are guaranteed the Acquire-Release ordering even though you didn't ask for it with your volatile type qualifier.
If you were actually thinking of POSIX signals or something similar then yeah, the POSIX requirements say volatile will work, seems like a bad idea to me, but your compiler and other tools are likely also built for POSIX so they've read the same documentation.
Re: Everything in C is undefined behavior
#637Earlier quoted context omitted.
No. An integer getting deterministically set to an unintended value is a bug. A bug is not the same thing as UB. (Even if it were non-deterministic, it would still not be anything like UB.) It's not the same ballpark, not even the same sport.
What if the wrapped index is used to construct an invalid pointer? It might be possible, not sure. What if the integer is used to read the wrong data from disk, or corrupt data on disk by writing to the wrong location?
Constructing an invalid pointer in rust is UB, yes, but integer wraparound is not.
> What if the integer is used to read the wrong data to a disk, or corrupt data on disk by writing to the wrong location?
Then it is a very bad bug.
> What if the program controls a nuclear power plant and the integer causes the control system to fail, causing memory errors due to radiation from the meltdown?
Then it is a very very bad bug.
> What if the wrapped integer causes the program to output the true name of god, and the programmer, in their last minutes of existence, looks up to see, overhead, without any fuss, the stars going out?
Ok, you got me, this one is UB.
Re: Everything in C is undefined behavior
#638Earlier quoted context omitted.
What if the compiler is able to use that to determine that a whole code path is dead, and then significantly improve the surrounding function because of that? Compilers optimise in multiple passes and removing things earlier can expose optimisation opportunities later that can affect other parts of the code too
> What if the compiler is able to use that to determine that a whole code path is dead, Then it should warn "unreachable code". > and then significantly improve the surrounding function because of that? It's not simply the removal that is the problem, it's that the code is silently removed.
Direct link to part 3 (but read the others first for context if you can): https://blog.llvm.org/2011/05/what-every-c-programmer-should...
You don’t want warnings for every piece of code in a library you’re not using or sanity check you added that isn’t supposed to be hit
And you can’t warn when you’re optimising based on undefined behaviour because you can’t know when it will happen, that is equivalent to the halting problem
If you warned whenever undefined behaviour could be happening then e.g. every single pointer deference would say “warning: compiling assuming pointer is not null or unaligned”
Re: Everything in C is undefined behavior
#639As for UB, the compiler has the final say. Nobody should write nontrivial c without understanding their compiler, the same as nobody should write c without understanding their text editor.
Code in other languages breaks between versions, in c there are projects with code from every version at once!
Looking at it another way, work put into a c compiler enables you to write nontrivial code.
Re: Everything in C is undefined behavior
#640The UB in unaligned pointers is even worse: an unaligned pointer in itself is UB, not only an access to it. So even implicit casting a void*v to an int*i (like 'i=v' in C or 'f(v)' when f() accepts an int*) is UB if the cast pointer is not aligned to int. It is important to understand that this is a C level problem: if you have UB in your C program, then your C program is broken, i.e., it is formally invalid and wron…
>an unaligned pointer in itself is UB, not only an access to it. Can someone point to where the standard states this?
> If the resulting pointer is not correctly aligned for the pointed-to type, the behavior is undefined.
However, unless I’m missing something, producing such a pointer from an integer is apparently not insta-UB? 6.3.2.2.5:
> An integer may be converted to any pointer type. Except as previously specified, the result is implementation-defined, might not be correctly aligned, might not point to an entity of the referenced type, and might be a trap representation
And later on 6.5.3.2.4:
> If an invalid value has been assigned to the pointer, the behavior of the unary * operator is undefined.
Which implies that the invalid pointer must have been obtained without being already undefined, right?