$ 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
Jokes often work with subverting expectations. In this case you're surprised by a message that doesn't belong and then you remember where it comes from and likely relate it with how frustrating those ever changing rules can be.
I thought it was funny because I've seen similar complaints from linters, e.g. clang-tidy's readability-identifier-length plus readability-identifier-naming, or pylint's invalid-name. (clang-tidy at least is smart enough to exempt loop counters.)
And on that day, I finally opened the Monolithic set of x86_64 programmer tomes, and finally figure out how to manually do linking.
You will be amazed how much of my skill with computers comes down to channeling Obsessive Defiance Disorder into digging into how to do what the compiler writers don't want to let me do, and doing it my way. With tests.
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.
This is one of the surviving improvements from JF Bastien's P1152 which was initially successful in deprecating most of the spurious use of volatile from C++ with a view to some day getting in there and actually doing MMIO properly.
Unfortunately too much of this will be unwound in C++ 23 because WG21 voted to un-deprecate all the volatile compound operators despite knowing nobody could even offer a rationale for why or how most of them would ever be correctly used.
P2327 would be in my "not angry just disappointed" category. Of course WG21 think rotten archaic C code should be valid C++ 23 and the belief from embedded devs who write this stuff that it's probably all fine despite no evidence whatsoever should be enough to sail through committee.
WG21 voted to amend the draft to un-deprecate all of the volatile compound assignments instead, at Kona IIRC.
#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.
You haven't programmed til you've come to the realization that billions of dollars worth of man hours are about to go down the toilet because of an assumption made 20 years ago, in a 4th order dependency, that you can't get rid of, and to rewrite is going to cost another couple million dollars, and spent a night with a bottle of whiskey wondering whether it's really all worth it.
Absolutely. I would also not use new/delete in that situation. It would depend on the audience whether they were still taught on a course, sometimes there is, and sometimes there isn't an educational purpose.
No, it’s not just theory. Like anything in C++, codebases and their styles widely vary. But my comment holds true for the vast majority of developers I have worked with over the last decade. With the exception of the special “placement new“ operator, it is nearly obsolete to use new and delete.
Hmm, I was at G until the recent decimation, and would have been surprised to see `new`, especially in new (heh) code, because it immediately raises the question of ownership, which means it costs time for every future reader.
Taking chromium as a proxy (though the style isn't identical), there are currently 5 or 6 times as many `make_unique` as `new`. (Some false positives on the word ‘new’ in strings, because I don't remember how to exclude them.)
If you are going to work with a legacy codebase, then sure. My comment was more about fresh codebases, which are fortunately the only ones I've worked on.
I would argue it is not for me at least. In my 2 current C++ commercial products of fair size one has single explicit allocation, the other does not have any.
If I was writing for example libraries of custom high performance containers the situation would have been different but still highly localized. And it is sort of very specialized type of development anyways.
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).
Why would you respond to a comment about a topic you don't understand and spread false information? You clearly cannot tell the difference between garbage collected language and smart pointers.
Smart pointers do not necessarily use reference counting. std::shared_ptr is reference counted, but std::unique_ptr is not. Needless to say that std::unique_ptr should always be the default choice and std::shared_ptr only used when actually needed.
like the other comment said, std::unique_ptr is not ref counted. Ref counting is one of the ways to implement garbage collection but it is not garbage collection by itself. C++ does not have garbage collection.
C++ does not have garbage collection in the standard library, just as shared_ptr was not part of the standard library in the past. You can currently have optional garbage collection in C++: https://github.com/pebal/sgcl
If you find yourself with the time, and the inclination, give Arrested Development a go. I thought it was fantastic. I think there is a reason that it always sat a little under the radar. You have to actively watch it. It's not suited to being on in the background.
Tobias: You know, Lindsay, as a developer, I have advised... a number of people to explore "modern C++," where everything is RAII, and you never have to write `new` or `delete`.
Lindsay: Well, did it work for those people?
Tobias: No, it never does. I mean, these people somehow delude themselves into thinking it might, but... but it might work for us.
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).
I'll be honest, I didn't get it at first. I thought initially that it was too complex for the teaching example. And then it clicked. You're rather smart aren't you! I guess 24, or 36, or 48 would have worked!
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]`.
Essentially correct. 33 sets up the pointer to appear to glibc as if it were a small, “normal” 32-byte allocation. The default behavior for glibc free() with a small allocation size will be to put it into the thread cache (tcache), which makes it immediately available to be reused by the same thread.
Although you should obviously never write code like this by yourself, understanding weird details like this is very helpful when exploiting memory error bugs in software, as it lets you understand how precisely to subvert the memory allocator to give you access to desired parts of memory.
Non-EV driver here; glad I did a search making the "obvious" reply. Surprisingly, "one pedal driving mode" is a thing. Its described as opt-in with a switch or setting, so I guess there's still a brake pedal. Which means some QA techs must have test plans with "switch off, step on brake pedal" and "switch on, step on brake pedal." Or maybe "switch on, step on brake pedal" is undefined behavior and the compiler can optimize it out.
EVs always have physical brakes and pedal too in addition to regenerative braking. Regenerative braking can't come close to the braking power of disc or drum brakes especially if the battery is full.
Sportier drivers may wish to brake and accelerate simultaneously (rev matching, weight transfer tricks). Normal cars just cut fuel when braking to avoid two-foot drivers burning their brakes.
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.