Java Panics at C++ Exceptions
Why is this Languages meme funny?
Level 1: Throwing Anything
This is funny because Java is like a teacher saying, "Only throw soft balls during class," while C++ calmly throws a weird mystery object and says, "It still counts." Java wants mistakes to be packaged neatly. C++ sometimes lets you package the mistake in whatever box the rules allow.
Level 2: Exception Rules
An exception is a way for a program to stop normal execution when something unusual or wrong happens. Instead of returning a normal value, the code throws an exception, and some other part of the program can catch it and decide what to do.
In Java, exceptions must come from the Throwable class family. Most custom exceptions extend Exception or RuntimeException. That means Java forces errors into a recognizable object hierarchy. Some exceptions are checked, meaning the compiler requires the method to declare them or the caller to handle them.
In C++, the thrown thing can be many kinds of values. It does not need to inherit from a special base class. That flexibility is powerful, but it also means strange code can be legal. The image's C++ snippet throws a lambda, which is normally a small function-like object. Throwing it as an exception is not useful in ordinary code, but it demonstrates how broad the language rule is.
The crying Java character is upset because Java programmers expect exceptions to be named error objects. The calm C++ character is funny because C++ accepts something that looks absurd and still treats it as a throwable value.
Level 3: Throw Whatever Compiles
The left side labels the crying figure JAVA and gives it the complaint:
Nooo! You can't just take something and throw it as an exception!
The right side labels the calm figure C++ and shows exactly that happening. This is classic LanguageComparison humor: Java is portrayed as rule-bound and object-hierarchy disciplined, while C++ is portrayed as the older, bearded engineer who has read the standard, found the trapdoor, and is now using it as the front entrance.
For experienced developers, the funny part is how accurately this matches each language's cultural reputation. Java's exception handling is explicit and institutionally flavored: define exception classes, decide whether something is checked or unchecked, declare or catch checked exceptions, and let the compiler complain when the paperwork is missing. C++ exception handling has type matching too, but the universe of throwable things is much broader. You can throw int, std::string, custom objects, pointers, and, in this image, an anonymous lambda object shaped like a dare.
The void*** parameter adds another layer of aesthetic violence. A triple pointer to void is not needed for the joke to work, but it makes the code look like it crawled out of a debugger at 2 AM. It signals SyntaxAbuse: technically meaningful symbols arranged to maximize psychological damage. The lambda body is empty, so the thrown object does not even carry useful error information. It is an exception as performance art.
The real-world pain underneath is that exception systems are not just syntax. They encode team conventions about failure. What should be exceptional? What should return an error value? What should crash? What should be logged? How do resources get cleaned up? Java teams often wrestle with over-declared checked exceptions and wrapper classes. C++ teams wrestle with ABI boundaries, destructor safety, exception guarantees, and codebases where someone thought throw 404; was a personality.
The meme works because both languages are being caricatured from a place of truth. Java sometimes feels like it wants every failure to wear a name badge. C++ sometimes feels like it will let you throw the name badge itself, then ask whether you remembered to define move semantics.
Level 4: Unwinding the Absurd
The C++ side is not merely being rebellious; it is leaning on how C++ models exceptions at the language and runtime level. The visible snippet is:
void foo()
{
// ...
throw ([&](void***){});
}
That throw operand is a lambda expression. In C++, a lambda expression creates an object of a unique, unnamed closure type. Because this particular lambda does not actually capture anything, even though it uses the capture-default syntax [&], the closure object is still easy for the compiler to materialize and copy. C++ can then create an exception object from that value and begin stack unwinding.
During unwinding, destructors for automatic objects are called as control exits each stack frame, and the runtime searches for a matching catch handler. This is where the meme becomes extra cursed: the thrown type is a compiler-generated closure type that ordinary source code cannot name by writing the same lambda text again. A handler like catch (...) can catch it, but a precise typed catch is basically unavailable unless the lambda object was first stored in a variable and the type was captured with something like decltype. The code is legalistic chaos: valid enough to compile in the right context, hostile enough to make future maintainers whisper.
Java made a very different design trade-off. A Java throw statement requires an expression assignable to Throwable, and the language further separates checked exceptions from unchecked RuntimeException and Error types. The exception system is tied to a class hierarchy, method signatures, and compiler enforcement. C++ treats exceptions more like typed values traveling through the unwinder. The type system still matters, but it is not forced into a single base class like Java's Throwable.
So the meme's technical core is not "C++ has no rules." It has many rules, and several of them were written by people who appear to enjoy edge cases as a recreational activity. The punchline is that C++ rules allow a beautifully ridiculous object, a nameless closure taking a void***, to become the thing hurled through the program's control flow.
Description
A two-panel Wojak-versus-Chad meme labels the crying figure on the left as "JAVA" and the calm bearded figure on the right as "C++". The Java side says, "Nooo! You can't just take something and throw it as an exception!" while the C++ side shows a dark code snippet: `void foo() { // ... throw ([&](void***){}); }`. The joke contrasts Java's constrained exception hierarchy with C++ exception semantics, where almost any copyable object can be thrown, including a grotesque-looking lambda type.
Comments
32Comment deleted
C++ saw Java's Throwable hierarchy and replied with `throw whatever_compiles;`.
*** is obviously some unicode bullshit so the identifier is not void but void*** Comment deleted
ligatures maybe Comment deleted
Fira code Comment deleted
Why would you even throw a lambda?.. Comment deleted
Well, at least it's not a trigraph. 😌 https://en.wikipedia.org/wiki/Digraphs_and_trigraphs Comment deleted
I dont see why you couldnt throw a lambda in Java. Exceptions are just objects like everything else and they can store any other object if extended to do so. Comment deleted
It'll be an exception with lambda stored in but not lambda itself Comment deleted
You could build the exception object with a lambda. I dont know that the distinction actually matters. It can be any object that implements throwable, which you can make any lambda object do. Comment deleted
Throwable is a class, but y're right in some point: it doesn't matter actually. Technically, lambda can be "transported" with throwing mechanism Comment deleted
in C++ you do not need to build anything you throw any Shit and you catch any Shit In Java you get advanced stacktraces thanks to that Exception base object, C++ simply does not give a shit Comment deleted
the difference is that in C++ you can throw anything, in Java you need to define it first Comment deleted
You can define it in a lambda, from a developers perspective it doesnt look much different from how you'd use a lambda in C++. It may be technically different, but functionally there isnt a significant difference. Comment deleted
developers like to write less, so there IS difference Comment deleted
If you're already a java dev the minor difference in amount of code is going to be pretty negligible. You're not going to decide on a language to build a project in based on the amount of code it takes to effectively throw a lambda function. Comment deleted
>You can define it in a lambda and then you do what with it when you catch a Throwable or an Exception which it extends? Comment deleted
Run it the same way you'd run a runnable. Assuming that's your objective in throwing a lambda function. Comment deleted
funny how you concentrate on the lambdas because the only reason you can throw them and then use the thrown value is because of under the hood JVM reflection. I said you can throw anything in C++. You did not upset my argument at all. For any value you throw the catching code either needs to have an external definition of it or rely on JVM reflection and even then you need to define this value as extension of Throwable or Exception. Comment deleted
The example was a lambda function and that's what I was responding to. The fact that you have to use JVM reflection is irrelevant. Everything's an object in Java, any object can be stored in an Exception, so with a little work you can throw anything you want. If the goal is to throw a lambda function, as shown in the example, it can be done in Java. How is irrelevant. Comment deleted
>The example was a lambda function and that's what I was responding to. You were responding to my message where I said that you can throw anything in C++. Comment deleted
Callable exception 😎 Comment deleted
Originally I the example is a lambda function. But if you really want to get into semantics, as everything in Java is an object, you can throw anything in Java. It just has to be wrapped with an Exception. How exactly it works is irrelevant. Comment deleted
that's not what "anything" is Comment deleted
Whatever dude. You're arguing for the sake of arguing. There's absolutely no substance. Comment deleted
That's wrong. It has to be Throwable. Exception is irrelevant. Comment deleted
I'm aware. An Exception is Throwable. So if it's Wrapped with an Exception it'll work. There are reasons you might prefer to use an Exception rather than just extending Throwable directly in this kind of use case. Comment deleted
indeed but it doesn't "have to be wrapped with an Exception" Comment deleted
☝️C++ guy won i guess. I’ll go with C++ in my next project Comment deleted
Try Rust Comment deleted
No, thanks, i take showers Comment deleted
I do too, at least once a month! /j Comment deleted
but you have no legs Comment deleted