I still remember one of my favorite linux bugs was due to the NULL behavior. It was roughly this read-from-p; if(p != NULL) write-to-p; since read-from-p is undefined if p is null, gcc could (and did) legally optimize out the NULL check, so you could end up writing to NULL. [edit] I noticed that this case of bug is actually mentioned in the regehr article that is linked.
What Every C Programmer Should Know About Undefined Behavior #1/3
11–19 of 19 posts
Re: What Every C Programmer Should Know About Undefined Behavior #1/3
#12I still remember one of my favorite linux bugs was due to the NULL behavior. It was roughly this read-from-p; if(p != NULL) write-to-p; since read-from-p is undefined if p is null, gcc could (and did) legally optimize out the NULL check, so you could end up writing to NULL. [edit] I noticed that this case of bug is actually mentioned in the regehr article that is linked.
If the compiler can optimize that away, what's the proper method for checking p?
int x = *p;
if (p == NULL) {
// p can't be NULL without having triggered
// undefined behavior in the first line, so
// this code is removed by the compiler.
return;
}
// ...
The fix is to stop dereferencing p before you know whether it's NULL or not: if (p == NULL) {
// Moving the check before the dereference
// avoids undefined behavior and resolves
// the issue.
return;
}
int x = *p;
// ...Re: What Every C Programmer Should Know About Undefined Behavior #1/3
#13Earlier quoted context omitted.
Because it can. This is undefined behavior we are talking about.
Sorry, I don't get it. The Intel manual says on UD2: "Raises an invalid opcode exception in all operating modes." What is here undefined? LLVM must not generate such instructions except it it really wants such a exception. (Like Linux's panic() does on x86)
Re: What Every C Programmer Should Know About Undefined Behavior #1/3
#14Earlier quoted context omitted.
Sorry, I don't get it. The Intel manual says on UD2: "Raises an invalid opcode exception in all operating modes." What is here undefined? LLVM must not generate such instructions except it it really wants such a exception. (Like Linux's panic() does on x86)
The original piece of C code has undefined behaviour, meaning LLVM can generate anything it wants. It happens to generate ud2 instructions (because it's better to crash hard and fast) but it could just as well print "puppies puppies puppies" a million times.
Re: What Every C Programmer Should Know About Undefined Behavior #1/3
#15"You don't know. The computer may levitate." is what they used to say in my C course at the uni.
Re: What Every C Programmer Should Know About Undefined Behavior #1/3
#16Earlier quoted context omitted.
Sorry, I don't get it. The Intel manual says on UD2: "Raises an invalid opcode exception in all operating modes." What is here undefined? LLVM must not generate such instructions except it it really wants such a exception. (Like Linux's panic() does on x86)
The original piece of C code has undefined behaviour, meaning LLVM can generate anything it wants. It happens to generate ud2 instructions (because it's better to crash hard and fast) but it could just as well print "puppies puppies puppies" a million times.
I'm not so sure about that. If you need to squeeze out a little more performance, code that is "technically undefined" can be more portable than dropping to ASM.
I think LLVM should emit a warning on code with undefined semantics and generate DWIM instructions instead of UD2s.
Re: What Every C Programmer Should Know About Undefined Behavior #1/3
#17This is actually guaranteed by the standard (although the language used is not "2s complement", but "repeatedly adding or subtracting one more than the maximum value that can be stored in the type until the value is in range").
C requires that these sorts of type conversions happen through unions: using pointer casts is not correct and undefined behavior results.
Actually, loading a member of a union other than the one most recently stored to is undefined behaviour too - it's just that using a union in this way falls into the "...both Clang and GCC nail down a few behaviors that the C standard leaves undefined." category. (And most other compilers besides - there is much historical usage of this).
Re: What Every C Programmer Should Know About Undefined Behavior #1/3
#18Earlier quoted context omitted.
The original piece of C code has undefined behaviour, meaning LLVM can generate anything it wants. It happens to generate ud2 instructions (because it's better to crash hard and fast) but it could just as well print "puppies puppies puppies" a million times.
> it's better to crash hard and fast I'm not so sure about that. If you need to squeeze out a little more performance, code that is "technically undefined" can be more portable than dropping to ASM. I think LLVM should emit a warning on code with undefined semantics and generate DWIM instructions instead of UD2s.
But you're correct that sometimes it can be expedient to exploit such technically undefined behavior. (I've committed this sin myself, most commonly in serializers/deserializers)
Re: What Every C Programmer Should Know About Undefined Behavior #1/3
#19edit: seems Blogger turned their -O knob to eleven http://status.blogger.com/