5 ms·
"falsehoods 'falsehoods programmers believe about X' authors believe about X"... All you need to know about null pointers in C or C++ is that dereferencing the
by ratmeadow 2y ago
"falsehoods 'falsehoods programmers believe about X' authors believe about X"...
All you need to know about null pointers in C or C++ is that dereferencing them gives undefined behaviour. That's it. The buck stops there. Anything else is you trying to be smart about it.
These articles are annoying because they try to sound smart by going through generally useless technicalities the average programmer shouldn't even be considering in the first place.
- MathMonkeyMan 2y agoUseless, but interesting. I used to work with somebody who would ask: What happens with this code? #include <iostream> int main() { const char *p = 0; std::cout << p; } You might answer "it's undefined behavior, so there is no point reasoning about what happens." Is it undefined behavior? The idea behind this question was to probe at the candidate's knowledge of the sorts of things discussed in the article: virtual memory, signals, undefined behavior, machine dependence, compiler optimizations. And edge cases in iostream. I didn't like this question, but I see the point. FWIW, on my machine, clang produces a program that segfaults, while gcc produces a program that doesn't. With "-O2", gcc produces a program that doesn't attempt any output.
- ratmeadow 2y agoI'm assuming it's meant to be: std::cout << *p; ? I still think discussing it is largely pointless. It's UB and the compiler can do about anything, as your example shows. Unless you want to discuss compiler internals, there's no point. Maybe the compiler assumes the code can't execute and removes it all - ok that's valid. Maybe it segfaults because some optimisation doesn't get triggered - ok that's valid. It could change between compiler flags and compiler versions. From the POV of the programmer it's effectively arbitrary what the result is. Where it gets harmful IMO is when programmers think they understand UB because they've seen a few articles, and start getting smart about it. "I checked the code gen and the compiler does X which means I can do Y, Z". No. Please stop. You will pay the price in bugs later.
- MathMonkeyMan 2y ago> I'm assuming it's meant to be: [...] Nope, I mean inserting the character pointer ("string") into the stream, not the character to which it maybe points. Your second paragraph demonstrates, I think, why my former colleague asked the question. And I agree with your third paragraph.
- ratmeadow 2y agoAh, I got confused for a minute why printing a character pointer is UB. I was thinking of printing the address, which is valid. But of course char* has a different overload because it's a string. You can tell how much I use std::string and std::string_view lol. I reckon we are generally in agreement. Perhaps I am not the best person to comment on the purpose of discussing UB, since I already know all the ins and outs of it... "Been there done that" kind of thing.
- johnnyanmac 2y ago>No. Please stop. You will pay the price in bugs later. indeed. It is called UB because that's basically code for compilers devs to say "welp don't have to worry about changing this" while updating the compiler. What can work in, say, GCC 12 may not work in GCC 14. Or even GCC 12.0.2 if you're unlucky enough. Or you suddenly need to port the code to another platform for clang/MSVC and are probably screwed.
- gerdesj 2y agoI think that reasoning about things is a good idea and looking at failure modes is an engineers job. However, I gather that the standard says "undefined", so a correct answer to what "happens with this code" might be: "wankery" (on the part of the questioner). You even demonstrate that undefined status with concrete examples. In another discipline you might ask what happens what happens when you stress a material near to or beyond its plastic limit? It's quite hard to find that limit precisely, without imposing lots of constraints. For example take a small metal thing eg a paper clip and bend it repeatedly. Eventually it will snap due to quite a few effects - work hardening, plastic limit and all that stuff. Your body heat will affect it, along with ambient temperature. That's before we worry about the material itself which a paper clip will be pretty straightforwards ... ish! OK, let's take a deeper look at that crystalline metallic structure ... or let's see what happens with concrete or concrete with steel in it, ooh let's stress that stuff and bend it in strange ways. Anyway, my point is: if you have something as simple as a standard that says: "this will go weird if you do it" then accept that fact and move on - don't try to be clever.
- immibis 2y ago"undefined" means "defined elsewhere".
- david-gpu 2y agoLOL. No. Some languages/libraries even make an explicit distinction between Undefined and Implementation-Defined, where only the latter is documented on a vendor-by-vendor basis. Undefined Behavior will typically vary across vendors and even within versions or whatnot within the same vendor. The very engineers who implemented the code may be unaware of what may happen when different types of UB are triggered, because it is likely not even tested for.
- immibis 2y agoSo it's defined in the compiler's source code. God doesn't roll a die every time you dereference null. Demons flying out of your nose would conform to the C++ standard, but I assure you that it would violate other things, such as the warranty on your computer that says it does not contain nasal demons, and your CPU's ISA, which does not contain a "vmovdq nose, demons" instruction.
- johnnyanmac 2y ago>I didn't like this question, but I see the point. These would be fine interviewing questions if it's meant to start a conversation. Even if I do think it's a bit obtuse from a SWE's perspective ("it's undefined behavior, don't do this") vs. a Computer scientists' perspective you took. It's just a shame that these days companies seem to want precise answers to such trivia. As if there's an objective answer. Which there is, but not without a deep understanding of your given compiler (and how many companies need that, on the spot, under pressure in a timed interview setting?)
- motorest 2y ago> These would be fine interviewing questions if it's meant to start a conversation. I don't agree. They sound like puerile parlour tricks and useless trivia questions, more in line in the interviewer acting defensively and trying too hard to pass themselves as smart or competent instead of actually assessing a candidate's skillset. Ask yourself how frequent those topics pop up in a PR, and how many would be addressed with a 5min review or Slack message.
- SR2Z 2y agoHaha all of the examples in the article are basically "here's some really old method for making address 0 a valid pointer." This isn't like timezones or zip codes where there are lots of unavoidable footguns - pretty much everyone at every layer of the stack thinks that a zero pointer should never point to valid data and should result in, at the very least, a segfault.
- SAI_Peregrinus 2y agoNot quite. Trivially, `&E` is equivalent to `E`, even if `E` is a null pointer (C23 standard, footnote 114 from section 6.5.3.2 paragraph 4, page 80). So since `&` is a no-op that's not UB. Also `*(a+b)` where `a` is NULL but `b` is a nonzero integer never dereferences the NULL pointer, but is still undefined behavior since conversions from null pointers to pointers of other types still do not compare equal to pointers to any actual objects or functions (6.3.2.3 paragraph 3) and addition or subtraction of pointers into array objects with integers that produce results that don't point into the same array object are UB (6.5.6).
- immibis 2y agoAre you writing C or C++ code or are you writing, for example C or C++ code for Windows? Because on Windows it's guaranteed to throw an access violation structured exception, for example.
- Maxatar 2y agoNo it's not, even with MSVC on Windows dereferencing a null pointer is not guaranteed to do anything: Here's a classic article about the very weird and unintuitive consequences of null pointer dereferencing, such as "time travel": https://devblogs.microsoft.com/oldnewthing/20140627-00/?p=633 https://devblogs.microsoft.com/oldnewthing/20140627-00/?p=63...
- sgerenser 2y agoI prefer: “Falsehoods programmers believe about X” articles with falsehoods considered harmful.
- pradn 2y ago> these articles are annoying You’re being quite negative about a well-researched article full of info most have never seen. It’s not a crime to write up details that don’t generally affect most people. A more generous take would be that this article is of primarily historical interest.
- ratmeadow 2y agoYou are right, it was overly negative, which was not nice. Read it as a half-rant then. These types of articles are my pet peeve for some reason.
- motorest 2y ago> You’re being quite negative about a well-researched article full of info most have never seen. I don't think this is true. OP is right: > These articles are annoying because they try to sound smart by going through generally useless technicalities the average programmer shouldn't even be considering in the first place. Dereferencing a null pointer is undefined behavior. Any observation beyond this at best an empirical observarion from running a specific implementation which may or may not comply with the standard. Any article making any sort of claim about null pointer dereferencing beyond stating it's undefined behavior is clearly poorly researched and not thought all the way through.
- pradn 2y agoI think you do point to a real issue. The "falsehoods programmers believe about X" genre can be either a) actual things a common programmer is likely to believe b) things a common programmer might not be be knowledgeable enough to believe. This article is closer to category b. But the category a ones are most useful, because they dispel myths one is likely to encounter in real, practical settings. Good examples of category a articles are those about names, times, and addresses. The distinction is between false knowledge and unknown unknowns, to put it somewhat crudely.