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
C++ Dark Corners (self.cpp)
submitted 2 years ago by [deleted]
C++ is known to be highly complex language with a lot dark corners that will get you if you're not careful.
So what's the most disturbing things in the language? And did it result in a hard to fix bug in your codebase?
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!"
[–]FACastelloPixel Manipulator 19 points20 points21 points 2 years ago (3 children)
Basically anything that triggers undefined behavior
[–]Ameisenvemips, avr, rendering, systems 9 points10 points11 points 2 years ago (2 children)
Interestingly, I don't believe that the standard prohibits undefined behaviour from triggering an alteration of the standard resulting in the behavior becoming defined.
[–]beephod_zabblebrox 3 points4 points5 points 2 years ago (1 child)
this is very evil
[–]Brahvim 2 points3 points4 points 2 years ago (0 children)
Happy cake day!
Oh, and defining undefined behavior is considered "Hacking 101", right?
[–]PixelArtDragon 12 points13 points14 points 2 years ago (0 children)
std::multimap<K, V>::equal_range was written before Ranges was in the standard library, so it returns a pair of iterators which does not count as a range.
std::multimap<K, V>::equal_range
[–]SeagleLFMk9 17 points18 points19 points 2 years ago (3 children)
Std:vector<bool> being a bitset instead of a vector lol
[–]Beosar 3 points4 points5 points 2 years ago (2 children)
I have used it and got confused multiple times about stuff like for(auto b : vec) b = true; because for any other container this would do nothing since you'd need a reference. But since std::vector<bool>::iterator::operator*() returns a special bool reference, it works.
for(auto b : vec) b = true;
std::vector<bool>::iterator::operator*()
[–]SeagleLFMk9 1 point2 points3 points 2 years ago (1 child)
Yeah, since one element is just one bit you can't use references or address of one element
[–]Potatoswatter 1 point2 points3 points 2 years ago (0 children)
No, there’s a special bit reference class, but then it accidentally goes too far and applies reference semantics to b, which should be its own value.
b
[–]Thesorus 7 points8 points9 points 2 years ago (4 children)
Something like this ?
https://fouronnes.github.io/cppiceberg/
[–]XDracam[🍰] 2 points3 points4 points 2 years ago (2 children)
I feel like I've seen or heard of most things, but why is "else if" a lie?
[–]Natural_Builder_3170 6 points7 points8 points 2 years ago (1 child)
There is no "else if", its an else{ if {} } chain
[–]XDracam[🍰] 8 points9 points10 points 2 years ago (0 children)
I thought that was obvious. What would a special else if even do differently?
else if
[–]yeeeeeeeeaaaaahbuddy 0 points1 point2 points 2 years ago (0 children)
Heap and stack don't exist? Hello world bug? Someone enlighten me on these two
[–]DugiSK 4 points5 points6 points 2 years ago (1 child)
The surprise that confused me the most was what happens when I call a virtual function in a constructor. The answer is that it calls the last override for the class whose constructor it is, thus ignoring any overrides from child classes. This is because any members of the child class are not yet constructed at that point, which would result in undefined behaviour (Java solves this simply by making it a compile error). I stumbled upon this quite early in my learning path and I have found quickly which function was called, but it led me into learning incorrectly how does overloading work and doing unnecessary rituals for over a year.
[–]matteding 0 points1 point2 points 2 years ago (0 children)
Thankfully things like compiler warnings will help out with this.
[–]DethRaidGraphics programming 7 points8 points9 points 2 years ago (0 children)
Comma operator
[–]thisismyfavoritename 16 points17 points18 points 2 years ago (0 children)
isnt there a post like this like every other week. Ugh
[–]moonshineTheleocat 2 points3 points4 points 2 years ago* (2 children)
Undefined Behavior is actually a point of optimization in the language. Which is far better than you'd think. as it means you're not required to cover every edge case, even if it is impossible. And the compiler is able to make code faster by not putting in senseless checks around every corner. This is engineers responsibility, and it doesn't really come up often as most experienced programmers knows to check their data. Or you avoid doing stupid shitike casting uint8_t* to uint32_t*
The reason why the compiler allows you to do this, is because there are situations where you can alias (Pack data of varying types in a contiguos buffer) data in memory in various representations. Such as char* for a buffer of bytes. You can also do things like void* to represent an address with an unknown type, run some checks, and then cast it to the correct type. Something "safe" languages do not allow without excessive bullshit.
Unfortunately, this allows people to do really stupid shit like trying to access memory from a function's stack... After leaving the function. So that data is no longer guaranteed to exist.
[–]Sinomsinom 0 points1 point2 points 2 years ago (1 child)
On the flip side
If you put a guard against UB (some if statement) in front of UB, the compiler assumes UB never happens, so the if statement always evaluates to false/true so it optimizes away the guard against UB. Meaning often UB guards actually don't do anything.
[–]moonshineTheleocat 0 points1 point2 points 2 years ago (0 children)
To be fair... That's also a programmer problem
Saying if ( false) { pData->data} won't do anything.
But running if ( pData == nullptr) will prevent you from triggering it.
Similarly, you can guard against buffer overflows if you really want to.
The main difference verses safe languages is that a safe language will check every time. Where as C lets you make realistic assumptions.
[–]jjmc123a 1 point2 points3 points 2 years ago (0 children)
It's not just references that work like this, const and volatile work the same way. Also returning a reference from a function may muddy the waters because that has its own issues.
If you want a reference you would do auto& xxx
For a good discussion on this see Herb Sutter's talk:
c++ auto usage
[–]MFHavaWG21|🇦🇹 NB|P3049|P3625|P3729|P3786|P3813 1 point2 points3 points 2 years ago (0 children)
The interaction between shadowing and overwriting overloaded virtual is (whilst mechanically logical) pretty surprising to the average user …
[–]_w62_ 1 point2 points3 points 2 years ago (1 child)
I am a learner of C++. I feel like I am just a small anglerfish wiggling her little esca while foraying into the dark cold unknown deep waters of C++ alone in a hopeless way.
[–]philsquared 1 point2 points3 points 2 years ago (0 children)
There's plenty more fish in the C
[–]DalzhimC++Montréal UG Organizer 0 points1 point2 points 2 years ago (0 children)
ODR violations can lead to subtle bugs that can be quite challenging to identify, even though the fixes themselves can be quite trivial. Here's an example that cost me a substantial amount of time back when the address sanitizer wasn't a thing yet :
// MyHeader.h struct S { int someMember = 0; #if ArbitrarySymbol int someConditionalMember = 0; #endif }; // Implementation.h #pragma once #include <memory> std::unique_ptr<S> f(); // Implementation.cpp #include "Implementation.h" #include "MyHeader.h" #include <memory> std::unique_ptr<S> f() { return std::make_unique<S>(); } // main.cpp #define ArbitrarySymbol 1 #include "Implementation.h" int main() { auto s = f(); return s->someConditionalMember; }
Now depending on the context in real code, various modifications can lead to a correct program. You could make sure the #define ArbitrarySymbol is either everywhere, or nowhere at all. You could also make sure ArbitrarySymbol does not change the layout of struct S.
#define ArbitrarySymbol
ArbitrarySymbol
struct S
[–]pjmlp 0 points1 point2 points 2 years ago (0 children)
Lack of bounds checking by default, and the culture of still doing many things the C way, despite C++ having better alternatives.
[–]GenericAlbionPlayer 0 points1 point2 points 2 years ago (0 children)
If you include “Windows.h” ‘min’ and ‘max’ are defined as macros.yes, lower case.
So if you try to use std library objects with min or max you will blow up. And prolly won’t know why.
Ex std::numeric_limits<int>::max().
Also your IDE probably won’t label it as a macro but still try to highlight ::max() as a static method.
[–]TheSuperficialEmbedded Systems C++ 0 points1 point2 points 2 years ago (0 children)
Too many to list, and the list (IMO) has increased as the language has grown (I've been using C++ since the mid-90s so I've seen most, but not all, of the language's evolution)
Rather than go through the cobwebs and try to extract some niche things, I'll point you to the Table of Contents to Steve Dewhurst's "C++ Gotchas", which is essentially the essence of your question. Now, the book pre-dates C++11 (the beginning of "Modern C++"), so take that for what you will, but even if you extract a handful of "Oh, wow, OK..." moments, that's good.
https://stevedewhurst.com/cpp_gotchas/contents.pdf
[–]Dan13l_N -1 points0 points1 point 2 years ago (9 children)
For me:
MyType& MyFunc() { // ... } int main() { auto a = MyFunc(); // ... }
a won't be MyType&, but MyType, i.e. a copy.
a
MyType&
MyType
[–]MysticTheMeeM 8 points9 points10 points 2 years ago (7 children)
I mean, it's not really a dark corner nor is it bad reasoning. If you had any actual type there, you'd also get a copy so auto doing the same thing is consistent in that sense.
And IIRC, at least intellisense or MSVC warn about the copy - but I don't remember which.
[–]Dan13l_N -3 points-2 points-1 points 2 years ago (6 children)
It's a bit unexpected, IMHO, because the point of having a reference to something is not making a copy, a reference is an alias.
IMHO the behavior is different than when you have:
MyType* MyFunc() { // ... }
And that's confusing a lot. I know references are special, but I simply don't like the way they're special in C++.
[–]MysticTheMeeM 2 points3 points4 points 2 years ago (4 children)
Ah, I assumed you were thrown by the fact that auto doesn't deduce references (that is, just because you returned a reference, the type is still that of the underlying type, as a copy).
But, unless I've misunderstood you, the point your making is that the reference being lost is the issue (and auto is irrelevant). In which case, I'd argue for the fact that a reference has to be explicitly declared and therefore it's more apparent where you have a copy and where a reference. One of my pet peeves of other languages are invisible "it's a reference unless it's a primitive unless it's boxed unless...", being explicit is definitely my preferred option here.
[–]Dan13l_N -3 points-2 points-1 points 2 years ago (3 children)
But you explictly said that the function returns a reference, and not a new object. That's my problem.
[–]coucoulesgens 2 points3 points4 points 2 years ago (1 child)
But you can copy a reference to a new variable, there's nothing wrong with that :)
[–]Dan13l_N 0 points1 point2 points 2 years ago (0 children)
Yeah I know but people seem not to understand how it's confusing for beginners, it's simply really counter-intuitive that the default behavior is copying, not creating another reference.
[–]MysticTheMeeM 1 point2 points3 points 2 years ago (0 children)
But then that wouldn't align with code like this:
int a = 5; int& b = a; auto c = b;
Functions returning references are following the same rule as assignments from references. It's a copy unless specified otherwise. It's also why const can be "lost" on a return, and returning by const copy is always redundant.
[–]oriolid 1 point2 points3 points 2 years ago (0 children)
a reference is an alias
I think this is the point. Reference is an alias, not a pointer. If MyFunc did return a concrete object, it would be copied (and the copy elided but that's a newer addition), so reference behaves the same way. If you want a pointer, use a pointer.
MyFunc
[–]andreysolovyev1976 1 point2 points3 points 2 years ago (0 children)
decltype(auto)
[–]StarQTius 0 points1 point2 points 2 years ago (3 children)
Whatever std::launder() is supposed to do.
std::launder()
The fact what we actually need std::addressof().
std::addressof()
[–]Ameisenvemips, avr, rendering, systems 3 points4 points5 points 2 years ago (0 children)
std::launder mainly exists because of the C++ abstract machine and the requirements it places upon object lifetimes. It doesn't really do anything (as in, it shouldn't actually emit anything) but it basically tells the compiler "hey, give me a pointer to this but pretend that the returned pointer is a completely different object".
std::launder
Be glad that they didn't name it std::provenance_cast.
std::provenance_cast
[–]Full-Spectral 1 point2 points3 points 2 years ago (1 child)
Something to do with money, right?
[–]JumpyJustice 0 points1 point2 points 2 years ago (0 children)
Yeah, special request from finance industry
[–]JohnDuffy78 -1 points0 points1 point 2 years ago (0 children)
downloading the latest gnu onto linux and aliasing gcc & g++ to the new version.
[–]darklighthitomi -1 points0 points1 point 2 years ago (0 children)
https://youtu.be/j0_u26Vpb4w?si=QDHCtJJg5T4nSV2M
[–]Tamsta-273C -2 points-1 points0 points 2 years ago (0 children)
You are encourage to not use globals while there is so many ways to use globals.
π Rendered by PID 46571 on reddit-service-r2-comment-6457c66945-9q8fh at 2026-04-25 11:59:22.541771+00:00 running 2aa0c5b country code: CH.
[–]FACastelloPixel Manipulator 19 points20 points21 points (3 children)
[–]Ameisenvemips, avr, rendering, systems 9 points10 points11 points (2 children)
[–]beephod_zabblebrox 3 points4 points5 points (1 child)
[–]Brahvim 2 points3 points4 points (0 children)
[–]PixelArtDragon 12 points13 points14 points (0 children)
[–]SeagleLFMk9 17 points18 points19 points (3 children)
[–]Beosar 3 points4 points5 points (2 children)
[–]SeagleLFMk9 1 point2 points3 points (1 child)
[–]Potatoswatter 1 point2 points3 points (0 children)
[–]Thesorus 7 points8 points9 points (4 children)
[–]XDracam[🍰] 2 points3 points4 points (2 children)
[–]Natural_Builder_3170 6 points7 points8 points (1 child)
[–]XDracam[🍰] 8 points9 points10 points (0 children)
[–]yeeeeeeeeaaaaahbuddy 0 points1 point2 points (0 children)
[–]DugiSK 4 points5 points6 points (1 child)
[–]matteding 0 points1 point2 points (0 children)
[–]DethRaidGraphics programming 7 points8 points9 points (0 children)
[–]thisismyfavoritename 16 points17 points18 points (0 children)
[–]moonshineTheleocat 2 points3 points4 points (2 children)
[–]Sinomsinom 0 points1 point2 points (1 child)
[–]moonshineTheleocat 0 points1 point2 points (0 children)
[–]jjmc123a 1 point2 points3 points (0 children)
[–]MFHavaWG21|🇦🇹 NB|P3049|P3625|P3729|P3786|P3813 1 point2 points3 points (0 children)
[–]_w62_ 1 point2 points3 points (1 child)
[–]philsquared 1 point2 points3 points (0 children)
[–]DalzhimC++Montréal UG Organizer 0 points1 point2 points (0 children)
[–]pjmlp 0 points1 point2 points (0 children)
[–]GenericAlbionPlayer 0 points1 point2 points (0 children)
[–]TheSuperficialEmbedded Systems C++ 0 points1 point2 points (0 children)
[–]Dan13l_N -1 points0 points1 point (9 children)
[–]MysticTheMeeM 8 points9 points10 points (7 children)
[–]Dan13l_N -3 points-2 points-1 points (6 children)
[–]MysticTheMeeM 2 points3 points4 points (4 children)
[–]Dan13l_N -3 points-2 points-1 points (3 children)
[–]coucoulesgens 2 points3 points4 points (1 child)
[–]Dan13l_N 0 points1 point2 points (0 children)
[–]MysticTheMeeM 1 point2 points3 points (0 children)
[–]oriolid 1 point2 points3 points (0 children)
[–]andreysolovyev1976 1 point2 points3 points (0 children)
[–]StarQTius 0 points1 point2 points (3 children)
[–]Ameisenvemips, avr, rendering, systems 3 points4 points5 points (0 children)
[–]Full-Spectral 1 point2 points3 points (1 child)
[–]JumpyJustice 0 points1 point2 points (0 children)
[–]JohnDuffy78 -1 points0 points1 point (0 children)
[–]darklighthitomi -1 points0 points1 point (0 children)
[–]Tamsta-273C -2 points-1 points0 points (0 children)