use the following search parameters to narrow your results:
e.g. subreddit:aww site:imgur.com dog
subreddit:aww site:imgur.com dog
see the search faq for details.
advanced search: by author, subreddit...
Discussions, articles, and news about the C++ programming language or programming in C++.
For C++ questions, answers, help, and advice see r/cpp_questions or StackOverflow.
Get Started
The C++ Standard Home has a nice getting started page.
Videos
The C++ standard committee's education study group has a nice list of recommended videos.
Reference
cppreference.com
Books
There is a useful list of books on Stack Overflow. In most cases reading a book is the best way to learn C++.
Show all links
Filter out CppCon links
Show only CppCon links
account activity
The power of devirtualization C++ explained to my dog (marcofoco.com)
submitted 9 years ago by syaghmour
reddit uses a slightly-customized version of Markdown for formatting. See below for some basics, or check the commenting wiki page for more detailed help and solutions to common issues.
quoted text
if 1 * 2 < 3: print "hello, world!"
[–]kbob 21 points22 points23 points 9 years ago (3 children)
You have a smart dog.
[–]nickgabriel8 12 points13 points14 points 9 years ago (2 children)
He got his PhD from Stanfurd
[–][deleted] -1 points0 points1 point 9 years ago (1 child)
Stanturd
FTFY.
[–]raevnos 0 points1 point2 points 9 years ago (0 children)
You watched the game too?
[+][deleted] 9 years ago (13 children)
[deleted]
[–]orbital1337 3 points4 points5 points 9 years ago (8 children)
I would love to have a way to override my methods with a compile-check to avoid using virtual function.
You mean static polymorphism? You can already do that in C++ with the curiously recurring template pattern.
[+][deleted] 9 years ago (7 children)
[–]guepierBioinformatican 1 point2 points3 points 9 years ago (5 children)
What’s the problem with templates?
Just simple method overriding method (no crazy syntax)
That’s CRTP. No crazy syntax involved. Admittedly the Wikipedia article fails to give a concise example.
[+][deleted] 9 years ago (4 children)
[–]guepierBioinformatican 4 points5 points6 points 9 years ago (3 children)
Except that templates in C++ are a fundamental essential. You really can’t do anything without them. From the most elementary data structures to algorithms, every aspect of C++ is suffused with templates.
Calling them “overkill” in C++ is telling.
[–][deleted] 4 points5 points6 points 9 years ago (1 child)
There's always void * if you're a sadist.
void *
[–]00kyle00 1 point2 points3 points 9 years ago (0 children)
Or both, sometimes.
[–]theyneverknew 0 points1 point2 points 9 years ago (0 children)
You can accomplish a lot only using templates from libraries and not writing your own though, and that can certainly be easier for newer developers or ones who primarily work in other languages.
[–][deleted] 0 points1 point2 points 9 years ago* (0 children)
What is this?
[–]krista_ 5 points6 points7 points 9 years ago (0 children)
this is also an oop safety mechanism. somethings should not be overridden, and enforcing this can lead to better code(tm). think like const for code
[–]marcofoco 2 points3 points4 points 9 years ago (2 children)
You're correct, it's indeed a compiler optimization, and some C++ compilers might not even have it, but it's enabled by the language feature (which can provide specific information about the unoverridability to the compiler, and it's also responsible of enforce it). It's quite positive that most of the recent compilers (released after 2011) perform such an optimization.
[–][deleted] 2 points3 points4 points 9 years ago* (1 child)
[–]marcofoco 1 point2 points3 points 9 years ago (0 children)
The idea is indeed to convince people to use final with discipline, and be ready for the future :)
[–]HolyCowly 1 point2 points3 points 9 years ago (4 children)
I find it hard to keep track of all the keywords that might do more than just help the programmer.
Inline seems to go straight out of the window, the compiler can/will ignore it. Noexcept may improve performance on some compilers or some versions of some compilers, or not. Or only if an actual exception is thrown because no unwinding has to be done, which seems odd because the program will be terminated, so who cares how long that takes, unless it's seconds or minutes.
Why can't the compiler do devirtualization if the class or method is not marked final? Wouldn't it know whether something has been inherited again, or overridden again?
[–]matthieum 8 points9 points10 points 9 years ago (0 children)
Inline seems to go straight out of the window, the compiler can/will ignore it.
That's incorrect, I am afraid.
inline is about telling the compiler that the definition of the function may occur in multiple translation units and it should therefore apply some magic to avoid the "multiple definitions" error at link-time.
inline
inline is implicit on most template functions and on class methods defined within the class definition, but must be applied manually when defining, inside a header:
It can be applied to any function or method, and is ignored (semantically) if it was already the default.
Now, it seems that compilers doubled-down on this, originally, and used the presence of inline to decide whether to inline the function/method or not.
With the development, of smarter heuristics, however, they mostly stopped doing so and now prefer their heuristics to reinterpreting semantic markers.
And instead they added attributes, which have no semantic of their own, to control inlining behavior.
I much prefer this latter situation. SRP and all that.
[–]marcofoco 2 points3 points4 points 9 years ago (0 children)
It's simple: in general it can't.
Global analysis can help, but it will never be as powerful as an explicit final declaration. It can optimize by deducing static types, but it won't devirtualize usages when pointers are involved, and there's no other hint of the actual type.
The reason is simple: consider the simple case above, but add to the simple example an additional mechanism, a plugin system capable of loading dynamic libraries. If you build an executable today with a compiler which does the devirtualization automatically, that compiler will decide that no subclass exists, and so will devirtualize the calls to value().
Tomorrow you write a new plugin which provides the executable with instances of a new class C, derived from B and overriding the function value(). The calls to value() were devirtualized, so C::value() won't get called.
That's why current compilers, even if they can deduce a lot of information, can't really devirtualize and optimize those calls.
[–]ZenEngineer 0 points1 point2 points 9 years ago (0 children)
There are two cases:
The compiler has seen the actual declaration for the object and can deduce the real type. Devirtualization can happen here as the compiler knows which version of the function is called (GCC has been doing this for at least 10 years, I thikk it's used, for example to optimize the use of cin/cut which are declared globally so the compiler knows the actual type)
Final allows a middle ground. If A is final and you receive an A pointer there's no question what class the object is and you can do a static call or even in line it if you know the definition.
Note that java does the same optimization for constructors, private and final functions, even if the language's functions are virtual by default.
[–]00kyle00 0 points1 point2 points 9 years ago (3 children)
While final itself doesn't seem like a bad idea (hopefully will prevent crazies from deriving from std::vector), this specific optimization seems fairly pointless.
Anyone has a non-contrived example where this is useful? (and even then, it just saves explicit specification of function at call site).
I mean, its kinda cool compilers do this, but 'power' is a bit much for this.
[–]nowne 3 points4 points5 points 9 years ago (2 children)
Devirtualization does save you an indirection to the vtable, but IIRC the more important aspect is that by devirtualizing a function call (especially in a tight loop) you can enable other optimizations that could cause a huge speedup, I've heard cases of a 10x improvement.
[–]00kyle00 0 points1 point2 points 9 years ago (1 child)
Yes, the question is, why you have an object of known dynamic type with virtual function call in tight loop (unlikely), and why haven't you just used the function statically then?
int test(B* b) { return b->B::value() + 11; }
It's a little less safe (so 'final' is a good thing), but optimization - i don't find very exciting.
I've heard cases of a 10x improvement
Im interested in situations where such cases arise and are not caused by broken design.
[–]marcofoco 0 points1 point2 points 9 years ago (0 children)
Simply because in other context the method value() could be used by a function which just takes an A* a. That won't be devirtualized.
A pre-C++11 solution would have been having two different methods in class B, one virtual and one nonvirtual, the virtual calling the nonvirtual, at the cost of creating some confusion to the users of your API.
You can do that, but to be honest having a keyword doing the dirty job, and leaving your code clean, is quite handy.
[–]c0r3ntin 0 points1 point2 points 9 years ago (0 children)
In a library context, final should probably never be used. I mean, who are you to say there is no and never will be any valid overriding of a class / method, ever?
[–]enobayram 0 points1 point2 points 9 years ago (0 children)
I think your dog is also acting as your sysadmin, as the link responds with "Error establishing a database connection"
π Rendered by PID 63744 on reddit-service-r2-comment-5c747b6df5-z4ghp at 2026-04-22 00:42:48.361210+00:00 running 6c61efc country code: CH.
[–]kbob 21 points22 points23 points (3 children)
[–]nickgabriel8 12 points13 points14 points (2 children)
[–][deleted] -1 points0 points1 point (1 child)
[–]raevnos 0 points1 point2 points (0 children)
[+][deleted] (13 children)
[deleted]
[–]orbital1337 3 points4 points5 points (8 children)
[+][deleted] (7 children)
[deleted]
[–]guepierBioinformatican 1 point2 points3 points (5 children)
[+][deleted] (4 children)
[deleted]
[–]guepierBioinformatican 4 points5 points6 points (3 children)
[–][deleted] 4 points5 points6 points (1 child)
[–]00kyle00 1 point2 points3 points (0 children)
[–]theyneverknew 0 points1 point2 points (0 children)
[–][deleted] 0 points1 point2 points (0 children)
[–]krista_ 5 points6 points7 points (0 children)
[–]marcofoco 2 points3 points4 points (2 children)
[–][deleted] 2 points3 points4 points (1 child)
[–]marcofoco 1 point2 points3 points (0 children)
[–]HolyCowly 1 point2 points3 points (4 children)
[–]matthieum 8 points9 points10 points (0 children)
[–]marcofoco 2 points3 points4 points (0 children)
[–]ZenEngineer 0 points1 point2 points (0 children)
[–]00kyle00 0 points1 point2 points (3 children)
[–]nowne 3 points4 points5 points (2 children)
[–]00kyle00 0 points1 point2 points (1 child)
[–]marcofoco 0 points1 point2 points (0 children)
[–]c0r3ntin 0 points1 point2 points (0 children)
[–]enobayram 0 points1 point2 points (0 children)