I'm sorry, but the answer this website gives to 1. is wrong. See for yourself: int i; int i = 10; int main(int argc, char* argv[]){ return 0; } Try to compile it. It doesn't work (gcc.exe (GCC) 5.3.0), the error is: a.cc:2:5: error: redefinition of 'int i' int i = 10; ^ a.cc:1:5: note: 'int i' previously declared here int i; ^ Either I misunderstood the author and this example, or I do know C.
Judging by the .cc extension, you are compiling this with a C++ compiler. Quoting from Annex C (which documents the incompatibilities between C++ and ISO C) of the C++ standard: Change: C++ does not have “tentative definitions” as in C E.g., at file scope, int i; int i; is valid in C, invalid in C++. This makes it impossible to define mutually referential file-local static objects, if initializers are restricted to t…
I Do Not Know C: Short quiz on undefined behavior (2015)
141–150 of 189 posts
Re: I Do Not Know C: Short quiz on undefined behavior (2015)
#142Earlier quoted context omitted.
It's easy to see the problem in the null pointer case. The compiler deduction is that the null test is redundant, but it's not actually redundant. Therefore the compiler "proves" a false theorem. That the standards rules permit the compiler to deduce false things would be, in normal engineering analysis, considered to show a failure in the rules, but the bureaucratic mindset holds that the rules are always, by defini…
> Therefore the compiler "proves" a false theorem. In the axiomatic system implied by the standard, the hypothetical compiler being discussed can prove that the null check can be eliminated. The fact that you believe this axiomatic system is inconvenient does not constitute a refutation of the truth of the theorem. > If the compiler is unable to prove a transformation preserves correctness, it should not do the trans…
Re: I Do Not Know C: Short quiz on undefined behavior (2015)
#143Earlier quoted context omitted.
> Therefore the compiler "proves" a false theorem. In the axiomatic system implied by the standard, the hypothetical compiler being discussed can prove that the null check can be eliminated. The fact that you believe this axiomatic system is inconvenient does not constitute a refutation of the truth of the theorem. > If the compiler is unable to prove a transformation preserves correctness, it should not do the trans…
the post that brought this to my attention discussed how a security error in Linux was created by this "optimization".
The compiler didn't create a security bug by removing the null check. The bug was created by the programmer when he didn't check for null before dereferencing the pointer. Even with the check, the program contained a bug.
Re: I Do Not Know C: Short quiz on undefined behavior (2015)
#144I'll be honest, I didn't find any of these to be particularly surprising. If you've been using C and are familiar with strict-aliasing and common UB issues I wouldn't expect any of these questions to seriously trip you up. Number 2 is probably the one most people are unlikely to guess, but that example has also been beaten to death so much since it started happening that I think lots of people (Or at least, the peopl…
Re: I Do Not Know C: Short quiz on undefined behavior (2015)
#145Earlier quoted context omitted.
I would agree that strict-aliasing is a hurt point for a lot of C devs, which is unfortunate. I'd only suggest that in general, if the strict-aliasing rule is coming into play you're probably already doing some really shady to begin with. Like in this example, casting a `long ` to an `int ` is likely a bad way to go about things even without worrying about strict-aliasing. In a lot of ways, I'd say that problems with…
A common class assignment or interview question is to write your own memcpy. Towards the end you usually start optimizing it by copying multiple bytes at once. That is undefined behavior. You cannot just cast a pointer to uint32_t* and start using it, unless the underlying object is actually uint32_t. In practice it works fine, so people don't care. We'll see what future compilers will do, especially when the homemad…
Re: I Do Not Know C: Short quiz on undefined behavior (2015)
#146Honestly, Optimizing compilers will kill C. It killed the one thing C was good at - simplicity (you know exactly what happens where, note I'm not saying speed, as C++ can be quite a bit faster than C). Now, due to language lawyering, you can't just know C and your CPU, you have to know your compiler (and every iteration of it!). And if you slip somewhere, your security checks blow up ( http://blog.regehr.org/archives…
Re: I Do Not Know C: Short quiz on undefined behavior (2015)
#147Earlier quoted context omitted.
If you want the compiler to leave the dereferences in, use `-fno-delete-null-pointer-checks` or ask your compiler vendor for an equivalent option. Compilers delete null pointer checks by default (on typical platforms) because it's what most users want.
But the null pointer check was left in. (And, sure enough, adding -fno-delete-null-pointer-checks makes no difference.)
foo(int*): # @foo(int*)
test rdi, rdi
je .LBB0_1
mov edi, dword ptr [rdi]
jmp bar(int) # TAILCALL
.LBB0_1:
ret
Only GCC does the kind of aggressive optimization the article mentions (and might need to be tamed by -fno-delete-null-pointer-checks).Re: I Do Not Know C: Short quiz on undefined behavior (2015)
#148Earlier quoted context omitted.
If you want to phrase it like that, a compiler tries to prove conjectures and performs actions (usually code and data elimination) based on whether it can prove them or their negatives. Sometimes it can't do either. I don't see where you're going, though.
It's easy to see the problem in the null pointer case. The compiler deduction is that the null test is redundant, but it's not actually redundant. Therefore the compiler "proves" a false theorem. That the standards rules permit the compiler to deduce false things would be, in normal engineering analysis, considered to show a failure in the rules, but the bureaucratic mindset holds that the rules are always, by defini…
You could argue the rules are "wrong", but that's a totally different topic.
Re: I Do Not Know C: Short quiz on undefined behavior (2015)
#149Earlier quoted context omitted.
This battle has been fought and lost. If you require sensible behaviour, just move on and use a language that offers it. C compilers will do what makes them look good on benchmarks, and various "friendly C" efforts have been tried and failed.
Au contraire - gcc and clang both appear to do the right thing now.
Re: I Do Not Know C: Short quiz on undefined behavior (2015)
#150Earlier quoted context omitted.
A common class assignment or interview question is to write your own memcpy. Towards the end you usually start optimizing it by copying multiple bytes at once. That is undefined behavior. You cannot just cast a pointer to uint32_t* and start using it, unless the underlying object is actually uint32_t. In practice it works fine, so people don't care. We'll see what future compilers will do, especially when the homemad…
You can cast from char* to uint32_t* and start using it. I forget the exact standardese, but there is an execption for char*.
Also, apparently uint8_t may not be a character type.