$ gcc -xc - <<<"int main(int argc, char **argv) { long long long a; return 0; }"
<stdin>: In function ‘main’:
<stdin>:1:45: error: ‘long long long’ is too long for GCC
> This label is the target of a goto from outside of the block containing this label AND this block has an automatic variable with an initializer AND your window wasn't wide enough to read this whole error message
That's more like ++C. You need "ADD 1 TO COBOL RETURNING COBOL"... which elicits another C++ joke: that it would have been nice to get to use the better version, but someone used the wrong operator, so what we have is certainly complicated but probably just more of the same.
My favorite, best told while among C programmers involuntarily debugging some gnarly C++ is, "Man, I swear, the dude that invented C++ doesn't know the difference between increment and excrement."
Narrator: It's at this point Michael realized the futility of C++ and promptly learned Rust over a couple of beers pondering if he will ever survive the oncoming AI apocalypse.
#include <iostream>
using namespace std;
class BadProgrammer {
public:
void yep() {
delete this;
}
};
int main() {
auto x = BadProgrammer{};
x.yep();
cout << "You are a terrible engineer and should feel bad, but don't worry because this will never print." << endl;
return 0;
}
g++ -Wall -Wextra -Wpedantic main.cc # compiles just fine
clang++ -Wall -Wextra -Wpedantic main.cc # also compiles just fine
FWIW the behavior of delete on a pointer that isn’t either null or returned from new is undefined.
So a conforming C++ compiler doesn’t have to diagnose this mistake, and similarly the compiled program doesn’t have to do anything meaningful either. For example, just ignoring the delete and printing the message is as valid a result as the more useful crash at the site of the bad operation.
I was surprised to see it not mentioned in the post -- the most obvious reason this joke should be retired is not the reference to a television show but rather the modern practice of never using new or delete at all in C++ code. Modern C++ avoids these pitfalls and I think it's been 10 years since I've written the words the new or delete.
I frequently work with companies that have old, large codebases. A key requirement of the training in that environment is that attendees are able to read existing production code. In some cases that's over twenty years old and millions of lines of code. new/delete is just part of that reality. We teach them without encouraging their use.
It's still useful to teach them in my experience. It's hard to introduce smart pointers without explaining the problem they solve (i.e. wrong or missing uses of delete).
According to the TIOBE index, C++ is the fourth most popular programming language, and has been around for over 35 years, so easily a couple thousand people. The question is how many of them are on HN (probably dozens).
Hey brother! I always love a good quote back. I've occasionally had a 'there are dozens of us' response in the training room or remote chat. Always makes me smile.
I assume you have it on x86_64. I'm trying to make sense of that according to glibc implementation details[1] and Sys V/Itanium ABI.
Default new and delete just use malloc/free.
First 4 ints are interpreted as prev_size and size. prev_size is 0. 33 is 0b10001, size is 32 (bytes, so 8 ints), AMP is 0b001, so not in arena (default sbrk heap, I assume), not mmap'd, prev is used.
I didn't follow how the internal bookkeeping will be updated, but I assume 8 size chunk will be immediately reused on a following `new int[6]`.
It's recommended to use virtual destructors for objects that live on the heap. Say you have a base class pointer to an object of a derived class; with nonvirtual destructors the base class determines the destructor that is called, whereas with virtual destructors it's the derived class that chooses the form of the destructor.
u801e|3 years ago
klodolph|3 years ago
https://www.cs.cmu.edu/~jasonh/personal/humor/compile.html
> This label is the target of a goto from outside of the block containing this label AND this block has an automatic variable with an initializer AND your window wasn't wide enough to read this whole error message
dvh|3 years ago
c9capital|3 years ago
DeathArrow|3 years ago
You: $ gcc -xc - <<<"int main(int argc, char *argv) { long long long a; return 0; }"
Compiler: <stdin>:1:45: error: ‘long long long’ is too long for GCC
You: Do it again, damn it, but this time show no errors!
nvader|3 years ago
tskool3|3 years ago
[deleted]
mwcremer|3 years ago
It’s called “ADD 1 TO COBOL”
saurik|3 years ago
smcameron|3 years ago
dllthomas|3 years ago
jasoneckert|3 years ago
ithkuil|3 years ago
PaulDavisThe1st|3 years ago
lisper|3 years ago
pciexpgpu|3 years ago
wizofaus|3 years ago
jasoneckert|3 years ago
omoikane|3 years ago
planede|3 years ago
pcthrowaway|3 years ago
kordite|3 years ago
sacnoradhq|3 years ago
clang++ -Wall -Wextra -Wpedantic main.cc # also compiles just fine
akhosravian|3 years ago
So a conforming C++ compiler doesn’t have to diagnose this mistake, and similarly the compiled program doesn’t have to do anything meaningful either. For example, just ignoring the delete and printing the message is as valid a result as the more useful crash at the site of the bad operation.
unknown|3 years ago
[deleted]
unknown|3 years ago
[deleted]
jb1991|3 years ago
kordite|3 years ago
pjmlp|3 years ago
lgeorget|3 years ago
ltr_|3 years ago
Galanwe|3 years ago
What? How do you (de)allocate memory without new and delete?
If the answer is "smart pointers" then why bother use C++ in the first place, just use Go or something.
hinkley|3 years ago
unknown|3 years ago
[deleted]
kordite|3 years ago
hummus_bae|3 years ago
pklausler|3 years ago
favorited|3 years ago
kjellsbells|3 years ago
I've made a huge mistake.
zamnos|3 years ago
cozzyd|3 years ago
kordite|3 years ago
nneonneo|3 years ago
Bonus fun: try printing out the address of `tobias` and `new int[6]` afterwards :)
planede|3 years ago
Default new and delete just use malloc/free.
First 4 ints are interpreted as prev_size and size. prev_size is 0. 33 is 0b10001, size is 32 (bytes, so 8 ints), AMP is 0b001, so not in arena (default sbrk heap, I assume), not mmap'd, prev is used.
I didn't follow how the internal bookkeeping will be updated, but I assume 8 size chunk will be immediately reused on a following `new int[6]`.
Obviously don't write code like this.
[1] https://sourceware.org/glibc/wiki/MallocInternals
bregma|3 years ago
Undefined behaviour is no joke.
al_be_back|3 years ago
i wouldn't say that's an illegal op per se, if anything it's a pretty safe op! tobias only ever existed in thought, not in body :( :(
maybe a compiler WARN or IGNORED_OP
photochemsyn|3 years ago
taspeotis|3 years ago
HnUser12|3 years ago
(But maybe they do have an actual brake pedal?)
Mawr|3 years ago
devmor|3 years ago
geenew|3 years ago
geenew|3 years ago
Don't mock try all the time
Am4TIfIsER0ppos|3 years ago
bitwize|3 years ago
hulitu|2 years ago
UNIX haters handboook.
lr1970|3 years ago
ltr_|3 years ago
kordite|3 years ago
globalreset|3 years ago
kordite|3 years ago
justincredible|3 years ago
[deleted]
xiaodai|3 years ago
[deleted]
0xfedbee|3 years ago
FpUser|3 years ago