What are the often misunderstood concepts in c++?
-
similiar to: http://stackoverflow.com/questions/75538/hidden-features-of-c – Mitch Wheat Feb 18 '09 at 12:31
-
more like http://stackoverflow.com/questions/294018/what-are-some-c-related-idioms-misconceptions-and-gotchas-that-youve-learnt – Tim Matthews Feb 18 '09 at 12:32
-
1also similar to: http://stackoverflow.com/questions/174892/what-is-the-most-spectacular-way-to-shoot-yourself-in-the-foot-with-c – Scott Langham Feb 18 '09 at 12:34
38 Answers
C++ is not C with classes!
And there is no language called C/C++. Everything goes downhill from there.

- 530,221
- 131
- 937
- 1,214
-
4
-
4
-
C/C++ most certainly does exist; it's the concept of writing programs which you can compile as C but when compiled as C++ adds features or checking. This means you can make a codebase whose footprint does not *require* a C++ compiler, but benefits from it when available. Furthermore, C++'s whole raison d'etre was to permit mixtures of C and C++ code for gradual improvements--a fact people often forget. Of course, most people asking questions tagged both `c` and `c++` are not dealing with either scenario. But suggesting the discussion of hybridized C and C++ code is not legitimate is wrong. – HostileFork says dont trust SE Nov 18 '18 at 10:39
-
@HostileFork Nobody is suggesting this. I am saying C/C++ *the language* does not exist. Anyway, C++’s original design might have been intentionally such that code bases could be gradually lifted from C but this is no longer the case. A lot of modern, valid C code is simply not valid C++ and that’s OK. And C++ nowadays is no longer the same language as back in the days, so don’t confuse history with what’s currently true. – Konrad Rudolph Nov 19 '18 at 11:13
That C++ does have automatic resource management.
(Most people who claim that C++ does not have memory management try to use new and delete way too much, not realising that if they allowed C++ to manage the resource themselves, the task gets much easier).
Example: (Made with a made up API because I do not have time to check the docs now)
// C++
void DoSomething()
{
File file("/tmp/dosomething", "rb");
... do stuff with file...
// file is automatically free'ed and closed.
}
// C#
public void DoSomething()
{
File file = new File("/tmp/dosomething", "rb");
... do stuff with file...
// file is NOT automatically closed.
// What if the caller calls DoSomething() in a tight loop?
// C# requires you to be aware of the implementation of the File class
// and forces you to accommodate, thus voiding implementation-hiding
// principles.
// Approaches may include:
// 1) Utilizing the IDisposable pattern.
// 2) Utilizing try-finally guards, which quickly gets messy.
// 3) The nagging doubt that you've forgotten something /somewhere/ in your
// 1 million loc project.
// 4) The realization that point #3 can not be fixed by fixing the File
// class.
}

- 11,517
- 1
- 40
- 72
-
-1 please explain how and where doe sit have automatic resource management? – hasen Feb 19 '09 at 14:22
-
4It is ironic that the most correct answers to this question might be modded down the most, _because_ they are more often misunderstood. (That said, I should've mentioned several keywords to help people google the reference, such as RAII and the preference to allocate objects on the stack.) – Arafangion Feb 19 '09 at 22:39
-
Well, just edit the post, and justify the answer. imho, C++ really does *not* have automatic resource management, even if its proponents say so. – hasen Feb 19 '09 at 23:29
-
3@hasen j: C++ have an *optional* automatic resource management. In C++ the `auto` keyword is the default storage class for (stack-allocated) local variables. Heap-allocation, as marked by using the `new` keyword, are used to mark a resource for manual resource management. However, all too often, a programmer misused the `new` keyword and caused memory leaks; then they claim C++ does not have automatic resource management, when they just have disabled it. – Lie Ryan Sep 27 '10 at 14:31
-
All he is saying is: if you allocate a class on the stack, then when it goes out of scope, the object is destroyed and it's destructor called. It is a useful technique but I don't know that it is worthy of being called automatic memory management because one may have a good reason to allocate on the heap. – Eric M Jan 09 '11 at 04:16
-
Which is to say: there is a style of C++ programming called RAII which within the area it can be usefully applied and with properly written destructors ensures resources do not leak. This is not automatic memory management because the programmer is writing the code to implement the management in the destructor. Compare this to, say, Java where stuff that is not referenced anymore is reclaimed/destructed by the Java runtime. It's apples and oranges - in C++ the programmer has to manage destruction and RAII is a nice way to do it, but in Java the runtime does it automagically. – Eric M May 19 '11 at 04:39
-
And FWIW, about 15 years ago I wrote a Java app (my very 1st Java app & 3rd SQL query, I was so proud ;-). It looped over a huge set of results from a SQL query in a very tight loop. The first version crashed on out of memory... my loop was creating 'row objects' (after 15 years I cannot remember what the Java-ism for a row is) faster than the garbage collector could reclaim them. I scratched my head for a while and realized I could force garbage collection, scratched some more and just wrote a better SQL query. So... automatic garbage collection is only as good as the programmer using it! – Eric M May 19 '11 at 04:52
Free functions are not bad just because they are not within a class C++ is not an OOP language alone, but builds upon a whole stack of techniques.
I've heard it many times when people say free functions (those in namespaces and global namespace) are a "relict of C times" and should be avoided. Quite the opposite is true. Free functions allow to decouple functions from specific classes and allow reuse of functionality. It's also recommended to use free functions instead of member functions if the function don't need access to implementation details - because this will eliminate cascading changes when one changes the implementation of a class among other advantages.
This is also reflected in the language: The range-based for loop in C++0x
(next C++ version released very soon) will be based on free function calls. It will get begin / end iterators by calling the free functions begin
and end
.

- 496,577
- 130
- 894
- 1,212
-
hey, weren't you arguing for member functions a week or two ago? ;) I agree though. And grats on your gold badge! By the way, isn't it still C++0x? Last I heard, they were still aiming to finalize the spec in 09. – jalf Feb 19 '09 at 00:30
-
jalf, well herb sutter said at oct'08 that there will be a second community draft soon at around october'09. then i think they will await comments again and have a meeting, after which finally the new standard will come out in 2010. that's what i heard and why i call it c++1x :) – Johannes Schaub - litb Feb 19 '09 at 02:54
-
1I absolutely agree. Developers seem to put everything in a class, whether it belongs there or not. also I prefer c++0A instead of c++1X. – deft_code Feb 21 '09 at 15:48
-
Yes! The idea of moving any method which does not depend on class internals to a free function (in an associated namespace of course) somehow runs contrary to most programmers' "feelings," and I initially felt the same way, but when you think about it it makes perfect sense. – j_random_hacker Feb 23 '09 at 00:39
-
1It's called Interface Principle and it's the idea of Herb Sutter. It would be nice to give him some credit at least. http://www.gotw.ca/publications/mill08.htm – Piotr Dobrogost Jun 07 '09 at 20:58
-
4@Piotr, it was not Herb Sutters' article that convinced me that free functions are superior, but it was Scott Meyers' "How non-member functions improve encapsulation" that convinced me: http://www.ddj.com/cpp/184401197 Without having looked up who has had the most influence on this, I don't think this is something you can attribute to some single person. Rather, the mechanism and ideas have grown up in the community as a whole, and all members of it somehow attribute to the things that come out of it. – Johannes Schaub - litb Jun 09 '09 at 00:19
The difference between assignment and initialisation:
string s = "foo"; // initialisation
s = "bar"; // assignment
Initialisation always uses constructors, assignment always uses operator=
-
8I always do initialization with parenthesis (string s("foo");), to help keep the difference obvious. The difference between init and assignment inside a constructor is also misunderstood. – Chris Smith Feb 18 '09 at 14:33
-
-
Another example might be Object o(1); vs Object o = 1; where Object has both a copy constructor and a single argument constructor that takes an int. – James Schek Jul 28 '09 at 15:18
In decreasing order:
- make sure to release pointers for allocated memory
- when destructors should be virtual
- how virtual functions work
Interestingly not many people know the full details of virtual functions, but still seem to be ok with getting work done.

- 5,993
- 4
- 30
- 39
-
-
21. Use smart pointers for allocated memory. It'll make your life so much easier. – David Thornley Feb 18 '09 at 14:58
-
@David - you are right. However the question is about misunderstood concepts in C++, and memory management tops the list at least for what I have seen. – Sesh Feb 18 '09 at 15:13
-
-
Actually, once you know 3., 2. becomes easy. But you have to know what vtables are. – isekaijin Feb 19 '09 at 07:54
-
@Sesh: How about "1. Use smart pointers, or make sure to delete raw pointers to allocated memory."? – David Thornley Nov 23 '09 at 21:52
-
@Sesh + @David: If you're really using C++, you should never be `delete`ing pointers manually (unless you yourself are implementing a smart pointer). Therefore I'd say that itself is a misunderstanding. – Billy ONeal Sep 24 '10 at 17:35
The most pernicious concept I've seen is that it should be treated as C with some addons. In fact, with modern C++ systems, it should be treated as a different language, and most of the C++-bashing I see is based on the "C with add-ons" model.
To mention some issues:
While you probably need to know the difference between delete
and delete[]
, you should normally be writing neither. Use smart pointers and std::vector<>
.
In fact, you should be using a *
only rarely. Use std::string for strings. (Yes, it's badly designed. Use it anyway.)
RAII means you don't generally have to write clean-up code. Clean-up code is bad style, and destroys conceptual locality. As a bonus, using RAII (including smart pointers) gives you a lot of basic exception safety for free. Overall, it's much better than garbage collection in some ways.
In general, class data members shouldn't be directly visible, either by being public
or by having getters and setters. There are exceptions (such as x and y in a point class), but they are exceptions, and should be considered as such.
And the big one: there is no such language as C/C++. It is possible to write programs that can compile properly under either language, but such programs are not good C++ and are not normally good C. The languages have been diverging since Stroustrup started working on "C with Classes", and are less similar now than ever. Using "C/C++" as a language name is prima facie evidence that the user doesn't know what he or she is talking about. C++, properly used, is no more like C than Java or C# are.

- 56,304
- 9
- 91
- 158
-
A C program that compiles as C++ is not normally good C? Nearly all C programs compile as C++, in my experience. – Imbue Feb 19 '09 at 08:09
-
Depends on what it does. "int * a = (int *)malloc(...)" isn't really good C, and "int * a = malloc(...)" doesn't compile under C++. Wherever there's compromises, the C++ side is usually not as good C as the C side. – David Thornley Feb 19 '09 at 14:23
-
3`std::string` isn't badly designed -- it just doesn't have most of it's functionality as part of it's signature. Use STL style algorithms on it instead. Too many C++ programmers look at `std::string` as a crappy version of a Java or C# string, rather than as a full fledged STL container. – Billy ONeal Sep 24 '10 at 17:37
-
1AFAICT C++ is an open ended logical system via template programming. C is a closed system. In C, A is A, but in C++ A might be AA
. I don't know if this makes sense to you, but it does to me. – Eric M May 19 '11 at 05:14 -
@BillyONeal yes and add over that the very necessary boost string algorithms and it closes in on python or C#. and in C++11 there even are facets now to do some utf encoding. cf codecvt header – v.oddou Mar 04 '15 at 04:59
-
@DavidThornley: why you think that `std::string` is badly designed ? – Destructor Aug 13 '16 at 17:46
The overuse of inheritance unrelated to polymorphism. Most of the time, unless you really do use runtime polymorphism, composition or static polymorphism (i.e., templates) is better.

- 16,577
- 3
- 41
- 45
-
2
-
NOt limited to C++ for sure, although the use of templates gives more options than Java, for instance. – KeithB Feb 18 '09 at 14:25
-
Then again, Java does have generics now, but suffers from having to box/unbox primitive types... – Arafangion Feb 19 '09 at 02:40
-
4Java generics aren't a replacement for the template system in C++. See this question: http://stackoverflow.com/questions/498317/c-templates-and-java-generics-difference – KeithB Feb 19 '09 at 13:09
-
The static keyword which can mean one of three distinct things depending on where it is used.
- It can be a static member function or member variable.
- It can be a static variable or function declared at namespace scope.
- It can be a static variable declared inside a function.

- 167,383
- 100
- 513
- 979
-
I can only remember two of those three things: declaring a static method and declaring a static variable, what's the third one? – isekaijin Feb 18 '09 at 12:48
-
-
Note that usage #2 is deprecated. Unnamed namespaces are preferred to the static keyword for this use case. – Brian Neal Feb 18 '09 at 14:30
-
What am I missing? If unnamed namespaces can replace #2 then how do you distinguish between 2 identically named functions/variables that in the past would have different namespaces to delineate between them? – Dunk Feb 18 '09 at 15:08
-
Dunk: What do you mean? If they are in an unnamed namespace, they're not visible outside the current compilation unit, so they won't conflict with identically named symbols in other compilation units. And if they're in the same compilation unit, it's a violation of ODR, and illegal. – jalf Feb 19 '09 at 00:24
-
Arrays are not pointers
They are different. So &array
is not a pointer to a pointer, but a pointer to an array. This is the most misunderstood concept in both C and C++ in my opinion. You gotta have a visit to all those SO answers that tell to pass 2-d arrays as type**
!

- 496,577
- 130
- 894
- 1,212
Here are some:
- Using templates to implement polymorphism without vtables, à la ATL.
- Logical
const
-ness vs actualconst
-ness in memory. When to use themutable
keyword.
ACKNOWLEDGEMENT: Thanks for correcting my mistake, spoulson.
EDIT:
Here are more:
- Virtual inheritance (not virtual methods): In fact, I don't understand it at all! (by that, I mean I don't know how it's implemented)
- Unions whose members are objects whose respective classes have non-trivial constructors.

- 19,076
- 18
- 85
- 153
-
-
I don't understand point 1 – or rather, I understand it, but I don't agree with it, at all. – Konrad Rudolph Feb 18 '09 at 14:52
-
i agree with 1., but i don't see how it is a misunderstood concept? it's rather a feature of c++ than a misunderstood thing. can u please add what's misunderstood there? – Johannes Schaub - litb Feb 18 '09 at 23:21
-
@Konrad: If you don't agree with point 1, then at least you or the author misunderstood it. That's a 50% misunderstanding. And that's often enough for it to be a good answer to this question. [Maybe my logic's a bit perverse... I think I need sleep]. – Scott Langham Feb 18 '09 at 23:23
-
Scott i thought about the same, lol. If he says it's a valid point, and Konrad says it isn't, one of them didn't get it :p – Johannes Schaub - litb Feb 18 '09 at 23:27
Here is an important concept in C++ that is often forgotten:
C++ should not be simply used like an object oriented language such as Java or C#. Inspire yourself from the STL and write generic code.

- 6,100
- 26
- 31
-
Why not? It was primarily designed to support the object oriented programming paradigm. – Scott Langham Feb 18 '09 at 12:50
-
1Because it has no garbage collection. Also, because virtual functions are messed up. Also, it has no strings, so each library ships with its own string class. – hasen Feb 18 '09 at 12:56
-
Because it's more generic oriented that object oriented. See the STL. – Edouard A. Feb 18 '09 at 13:19
-
C++ supports OO fine, the difference is that you have to do a lot of headachy work compared to, say C#. This doesn't mean you shouldn't use it for OO... just that its more difficult to do it safely. At least imho – jheriko Feb 18 '09 at 13:24
-
Of course it does, but that's not how you should use it. Write templates. Write generic code. Don't limit yourself to OOP. Perhaps this is poorly phrased... – Edouard A. Feb 18 '09 at 13:26
-
3It is better if you restate your assertion: "C++ is much more than OO, if you look at it just as an OO language, you are missing important features like generic programming". – Ismael Feb 18 '09 at 14:05
-
Other languages have its pros and cons, but saying that Java & C# are just OO is plain wrong. – Ismael Feb 18 '09 at 14:08
-
The underlying message is that you should not write your programs in C++ like you would in Java an C#. – Edouard A. Feb 18 '09 at 14:26
-
I still think looking only at Java or C# is too narrow, but is just my opinion I guess. – Ismael Feb 18 '09 at 14:57
-
I don't pretend to be able to sum up all the complexity of C++ in two sentences. ;) – Edouard A. Feb 18 '09 at 15:27
-
-
I agree, the point is well made. C++'s OO features enable it's generic features, so use it's generic features too. – Rob K Feb 18 '09 at 18:08
-
I can't believe this got downvoted so many times!! guys, can anyone say with a straight face that you can write C#-Like code in C++???? – hasen Feb 18 '09 at 23:55
-
+1 from here. It's a good point. If you just want OOP, there are better languages out there. C++'s strengths is that it allows you to combine OOP with other paradigms, not least generic programming. – jalf Feb 19 '09 at 00:32
-
Given this:
int x = sizeof(char);
what value is X?
The answer you often hear is dependant on the level of understanding of the specification.
- Beginner - x is one because chars are always eight bit values.
- Intermediate - it depends on the compiler implementation, chars could be UTF16 format.
- Expert - x is one and always will be one since a char is the smallest addressable unit of memory and sizeof determines the number of units of memory required to store an instance of the type. So in a system where a char is eight bits, a 32 bit value will have a sizeof of 4; but in a system where a char is 16 bits, a 32 bit value will have a sizeof of 2.
It's unfortunate that the standard uses 'byte' to refer to a unit of memory since many programmers think of 'byte' as being eight bits.

- 69,698
- 10
- 71
- 108
-
5Your answer for '3' is wrong... It is true that x is will always be one - but your rationale is wrong! It is defined as one by the spec, not because it is the smallest addressable unit of memory. Some archs probably address bits, while others can't address less than 32 bits - x is still one! – Arafangion Feb 19 '09 at 00:00
-
1OK, perhaps my wording wasn't great there. However, it's the compiler writer that decides the size of a byte/char, not the hardware. On an IA32, a byte could be 16 bits even though the hardware can address to 8 bit resolution. Obviously, the compiler writer would choose a size that was most efficent – Skizz Feb 19 '09 at 00:36
-
You're worrding is weird. You say x is always one, and yet sizeof(char) will return either 2 or 4? I don't grok? – Chris K Jul 27 '09 at 23:30
-
It's even more unfortunate that "char" refers to a unit of memory now that we have Unicode. – dan04 Mar 12 '10 at 05:22
-
1The "beginner" sounds like the expert among them (being a little forgiving, since as an expert, he should have said that `sizeof(char)` is defined by the language standard as of C99 to be one *byte*). The "expert" sounds like the beginner, for both making no sense, being confusing, and ultimately wrong. The "intermediate" seems also a bit confused, but at least isn't spouting nonsense with over-confidence, as `sizeof` other data types do in fact depend on architecture and/or compiler. Pointing out that `sizeof(char)=1` is the exception should be simple enough. – swalog Feb 15 '15 at 20:51
-
As a clarification, the reason why the "expert" is ultimately wrong, is because the compiler doesn't care how many bits are actually used to store a `char` in memory (aside from being `>=8`). The `sizeof` a type is determined by the compiler, and not the hardware (thought it is highly unusual for them not to match). If a byte on that machine is represented by 16 bits, then `CHAR_BIT` has the value 16. Thus, an `int` takes up at least 16 bits when stored in memory. If `sizeof(int)=4`, then it means 16*4 bits, but the only requirement is for `sizeof(int) >= sizeof(short) >= sizeof(char) = 1`. – swalog Feb 15 '15 at 21:19
-
@swalog: ? (Oh, and I'm sure I've used systems where chars are 7bits and heard of ones where chars are 4bits) – Skizz Feb 16 '15 at 09:58
-
It seems like you are using 'char' as a hardware dependent unit of addressable n bits. I haven't seen 'char' being used in this context before. Usually, the used word is 'byte', commonly 8 bits, or 'octet', with no ambiguity. The C++ language doesn't care how many bytes the hardware uses to store a char (though >1 is wasteful), or how many bits a byte has, as far as `sizeof(char)` goes. Which makes the statement "in a system where a char is eight bits, a 32 bit value will have a sizeof of 4", not necessarily true, as its mixing hardware implementations and compiler choices. – swalog Feb 16 '15 at 10:43
-
The only reason I'm actually pointing this out, is because the original explanation causes confusion. That this somehow requires an "expert" understanding, because it is complicated. It really isn't. `sizeof(char)=1`, and otherwise returns the number of bytes used to store the type. The number of bits in a byte is usually 8, but not necessarily. The actual number is found in `CHAR_BIT`. And that is all the complexity and in-depth knowledge there is to it. I'd agree with: "in a system where a *byte* is eight bits, a 32 bit value will *(unless the compiler is silly)* have a sizeof of 4". – swalog Feb 16 '15 at 10:54
-
Correction: "in a system where a byte is eight bits, a 32 bit value will (unless the compiler is silly) have a sizeof of 4... *unless* the type queried is `char`, which will return 1 regardless". – swalog Feb 16 '15 at 11:31
-
@swalog: I think you're just reinforcing the idea that 'sizeof' is a complex beast which is often misunderstood. The 'expert' thing isn't about 'sizeof(char)' but the reason why 'sizeof(char)==1'. The language used in the standard is confusing in that 'byte' is not assumed to be eight bits which is what people first think of. It specifies 'CHAR_BIT' as the size in bits which sort of reinforces the confusion (why not 'BYTE_BIT'?). 'sizeof(int)' could be 2 but still be a 32bit number. – Skizz Feb 16 '15 at 16:52
a classic among beginners to c++ from c:
confuse delete
and delete[]
EDIT:
another classic failure among all levels of experience when using C API:
std::string helloString = "hello world";
printf("%s\n", helloString);
instead of:
printf("%s\n", helloString.c_str());
it happens to me every week. You could use streams, but sometimes you have to deal with printf-like APIs.

- 97,545
- 26
- 194
- 236

- 3,443
- 2
- 19
- 14
-
-
I think beginners usually don't use the stl, just use C++ as C with classes. – davidnr Feb 19 '09 at 15:51
-
-
visual c++ allows as an extension to pass non-pod classes to var-arg functions, i read. for example passing a CString directly. but i forgot the specific semantics – Johannes Schaub - litb Feb 19 '09 at 19:32
-
1@mannicken: According to the standard 5.2.2.7: "If the argument [matching an ellipsis] has non-POD class type, the behaviour is undefined." – j_random_hacker Feb 23 '09 at 00:56
-
-Wformat is your friend, to prevent this from happening (at least using GCC and probably ICC). – Tom Aug 26 '09 at 00:40
C++ is a multi-paradigm language. Many people associate C++ strictly with OOP.

- 56,777
- 5
- 32
- 27
Pointers.
Dereferencing the pointers. Through either .
or ->
Address of using &
for when a pointer is required.
Functions that take params by reference by specifing a &
in the signature.
Pointer to pointers to pointers ***
or pointers by reference void someFunc(int *& arg)

- 5,031
- 8
- 38
- 45
-
Sorry couldn't figure out SO's escape characters so may appear weird. – Tim Matthews Feb 18 '09 at 12:37
-
-
You can't have pointers to references, they're illegal. You can have references to pointers, though. – Adam Rosenfield Feb 18 '09 at 23:31
-
@Adam Rosenfield sorry it was about 2am when I posted this. I have rearanged the last example. – Tim Matthews Feb 19 '09 at 01:23
There are a few things that people seem to be constantly confused by or have no idea about:
Pointers, especially function pointers and multiple pointers (e.g. int(*)(void*), void***)
The const keyword and const correctness (e.g. what is the difference between const char*, char* const and const char* const, and what does void class::member() const; mean?)
Memory allocation (e.g. every pointer new'ed should be deleted, malloc/free should not be mixed with new/delete, when to use delete [] instead of delete, why the C functions are still useful (e.g. expand(), realloc()))
Scope (i.e. that you can use { } on its own to create a new scope for variable names, rather than just as part of if, for etc...)
Switch statements. (e.g. not understanding that they can optimise as well (or better in some cases) than chains of ifs, not understanding fall through and its practical applications (loop unrolling as an example) or that there is a default case)
Calling conventions (e.g. what is the difference between cdecl and stdcall, how would you implement a pascal function, why does it even matter?)
Inheritance and multiple inheritance and, more generally, the entire OO paradigm.
Inline assembler, as it is usually implemented, is not part of C++.

- 3,043
- 1
- 21
- 28
-
1While #6 may be important, it has nothing to do with standard C++. Rather it is an extension for a specific OS. – KeithB Feb 18 '09 at 13:46
-
1Not to mention that #1, #2, #4, #5, and #8 apply just as much to C. – David Thornley Feb 18 '09 at 15:03
-
It is true that calling conventions are implementation specific, but I feel it is still important to understand their usage and why they may prevent code from functioning if not dealt with correctly since every implementation of C++ depends on them. Thanks for the feedback though. :) – jheriko Feb 18 '09 at 18:48
-
In-line assembler in the shape of the asm() declaration is part of Standard C++ (7.4/1) – Feb 18 '09 at 22:38
-
Isn't the language "assembly"? "Assembler" is the tool, like "compiler." =] – strager Feb 18 '09 at 23:33
-
@strager either "assembler" or "assembly language" but not "assembly" (speaking from 30 years assembler experience) – Feb 19 '09 at 01:29
-
- Pointers to members and pointers to member functions.
- Non-type template parameters.
- Multiple inheritance, particularly virtual base classes and shared base objects.
- Order of construction and destruction, the state of virtual functions in the middle of constructing an intermediate base class.
- Cast safety and variable sizes. No, you can't assume that
sizeof(void *) == sizeof(int)
(or any other type for that matter, unless a portable header specifically guarantees it) in portable code. - Pointer arithmetic.

- 5,326
- 29
- 29
-
I've gotten caught by your fourth bullet once or twice before. >_< Note: [u]intptr_t
must at least be the size of a pointer. – strager Feb 18 '09 at 23:36 -
Headers and implementation files
This is also a concept misunderstood by many. Questions like what goes into header files and why it causes link errors if function definitions appear multiple times in a program on the one side but not when class definitions appear multiple times on the other side.
Very similar to those questions is why it is important to have header guards.

- 496,577
- 130
- 894
- 1,212
If a function accepts a pointer to a pointer, void*
will still do it
I've seen that the concept of a void pointer is frequently confused. It's believed that if you have a pointer, you use a void*
, and if you have a pointer to a pointer, you use a void**
. But you can and should in both cases use void*
. A void**
does not have the special properties that a void*
has.
It's the special property that a void*
can also be assigned a pointer to a pointer and when cast back the original value is received.

- 496,577
- 130
- 894
- 1,212
-
an example use case? `void f(void *p) { int **a = (int**)p; *a = some_int_ptr; }` instead of `void f(void **p);` – Johannes Schaub - litb Aug 26 '09 at 00:19
NULL
is always zero.
Many confuse NULL
with an address, and think therefor it's not necessarily zero if the platform has a different null pointer address.
But NULL
is always zero and it is not an address. It's an zero constant integer expression that can be converted to pointer types.

- 496,577
- 130
- 894
- 1,212
I think the most misunderstood concept about C++ is why it exists and what its purpose is. Its often under fire from above (Java, C# etc.) and from below (C). C++ has the ability to operate close to the machine to deal with computational complexity and abstraction mechanisms to manage domain complexity.

- 2,230
- 6
- 33
- 51
Hehe, this is a silly reply: the most misunderstood thing in C++ programming is the error messages from g++ when template classes fail to compile!

- 1,027
- 2
- 8
- 21
Memory Alignment.

- 5,031
- 8
- 38
- 45
-
-
+1 because I don't even know what it means or why it matters, but I keep hearing about it – Apr 16 '09 at 21:04
std::vector
does not create elements when reserve is used
I've seen it that programmers argue that they can access members at positions greater than what size()
returns if they reserve()
'ed up to that positions. That's a wrong assumption but is very common among programmers - especially because it's quite hard for the compiler to diagnose a mistake, which will silently make things "work".

- 496,577
- 130
- 894
- 1,212
-
It just reserves memory, not construct objects to fill the unused space. – Eric M May 19 '11 at 04:56
C++ is not C with string and vector!

- 26,650
- 27
- 89
- 114
-
Ha! A lot of people just use it like C, *without* using string or vector. :) I never want to see a strcmp or strcpy in C++ code again! – Brian Neal Feb 18 '09 at 14:34
-
And what if you can't use the stl or boost because of platform restriction, but you need OO? You write your own string library (hopefully) and use strlen etc. internally, or you use char*'s and be done with it. – xan Feb 18 '09 at 15:57
-
@xan - why can't you use STL? I can understand about not wanting or being able to run boost, but STL is standard with all major compiler vendors. It is a horrifically bad idea to write your own string library when you can use std::string (even with all its faults). – Brian Neal Feb 18 '09 at 19:48
-
Using C++ like C is a valid C++ style. It was the goal of the language to build upon C, not remove it. – Chris de Vries Feb 18 '09 at 23:33
-
C++ is not a typical object oriented language.
Don't believe me? look at the STL, way more templates than objects.
It's almost impossible to use Java/C# ways of writing object oriented code; it simply doesn't work.
- In Java/C# programming, there's alot of
new
ing, lots of utility objects that implement some single cohesive functionality. - In C++, any object
new
ed must be deleted, but there's always the problem of who owns the object - As a result, objects tend to be created on the stack
- But when you do that, you have to copy them around all the time if you're going to pass them around to other functions/objects, thus wasting a lot of performance that is said to be achieved with the unmanaged environment of C++
- Upon realizing that, you have to think about other ways of organizing your code
- You might end up doing things the procedural way, or using metaprogramming idioms like smart pointers
- At this point, you've realized that OO in C++ cannot be used the same way as it is used in Java/C#
If you insist on doing oop with pointers, you'll usually have large (gigantic!) classes, with clearly defined ownership relationships between objects to avoid memory leaks. And then even if you do that, you're already too far from the Java/C# idiom of oop.
Actually I made up the term "object-oriented", and I can tell you I did not have C++ in mind.
-- Alan Kay (click the link, it's a video, the quote is at 10:33)
Although from a purist point of view (e.g. Alan Kay), even Java and C# fall short of true oop

- 161,647
- 65
- 194
- 231
-
Which is more expensive - copying memory, or constantly dereferencing references? I'm not sure if I would agree that copying the objects wastes alot of performance gains... If the object is large, though, then optimize it in the class! (Many std::strings use a reference, internally, afaik). – Arafangion Feb 19 '09 at 02:38
-
it doesn't matter which choice you follow, either way, you're already too far from the Java/C# idiom of oop. – hasen Feb 19 '09 at 08:07
-
1Arguably-what if you added a garbage collector, and only passed around smart pointers? Either way, it doesn't matter-you're abusing RAII, which is C++'s best feature, so you're right, even if someone somehow uses C# ways in C++, you've used the worst of both worlds. – Arafangion Feb 19 '09 at 22:43
-
Template meta-programming and object oriented programming are two different things. C++ supports both. – Eric M May 19 '11 at 05:00
C structs VS C++ structs is often misunderstood.

- 1,608
- 2
- 18
- 22
-
In what way? I understand that a C++ struct is identical to a class (except for default access specifier), but if you think of it as identical to a C struct, and use class for everything else, I think you end up with clearer code and no confusion. – KeithB Feb 19 '09 at 17:03
-
Just C++ stuct can have member functions but C struct cannot. C structs are just data, C++ structs benefit from ctor/dtor and inheritence. Everything is public in either. Look at eg LIBJPEG, a C library, and what it's authors called "poor man's object oriented programming": C structs with C function pointer members assigned to whatever C function the particular JPEG file represented by a struct being en/decoded requires. – Eric M May 19 '11 at 05:08
A pointer is an iterator, but an iterator is not always a pointer
This is also an often misunderstood concept. A pointer to an object is a random access iterator: It can be incremented/decremented by an arbitrary amount of elements and can be read and written. However, an iterator class that has operator overloads doing that fulfill those requirements too. So it is also an iterator but is of course not a pointer.
I remember one of my past C++ teachers was teaching (wrongly) that you get a pointer to an element of a vector if you do vec.begin()
. He was actually assuming - without knowing - that the vector implements its iterators using pointers.

- 496,577
- 130
- 894
- 1,212
-
1Schaub: IMO iterator is conceptually a pointer in the sense that an iterator points to a specific object. I agree though, that iterator is not a pointer in the sense of a "memory address". – Lie Ryan Sep 27 '10 at 14:49
I know this is old question but I thought object slicing / failure of polymorphism with objects on the stack worth mentioning. If I do not use C++ for six months, this one always comes out and bites me when I use the language again.
#include <iostream>
class base {
public:
base(int val) { var1 = val; };
virtual void doSomething() { var1 *= 2; };
int getVar1() { return var1; };
virtual ~base() { };
protected:
int var1;
};
class deriv : public base {
public:
deriv(int val) : base(val) { };
void doSomething() { var1 *= 4; };
};
void use_object_ptr(base *arg) {
arg->doSomething();
std::cout << arg->getVar1() << std::endl;
};
void use_object_copy(base arg) {
arg.doSomething();
std::cout << arg.getVar1() << std::endl;
};
int main(int argc, char **argv) {
deriv d(42);
deriv *p2d = new deriv(42);
use_object_ptr(p2d); // calls deriv::doSomething(), prints 168
use_object_copy(d); // calls base::doSomething(), prints 84
use_object_ptr(&d); // calls deriv::doSomething(), prints 168
return 0;
}

- 1,027
- 2
- 8
- 21
-
By default, always inherit base classes from a noncopyable class. virtual destructor ? => inherit from boost_or_whatever::noncopyable – Luc Hermitte Jul 28 '09 at 08:31
-
- That anonymous namespaces are almost always what is truly wanted when people are making static variables in C++
- When making library header files, the pimpl idiom (http://www.gotw.ca/gotw/024.htm) should be used for almost all private functions and members to aid in dependency management

- 435
- 4
- 7
-
I'll retort with "believing that anonymous namespaces and the `static` keyword are interchangeable". They get similar results, but using different means, and sometimes you want both. `static` variables don't show up outside of the compilation unit, whereas anonymous-namespaced variables do. That can make a huge difference in shared library name binding performance. – Tom Aug 26 '09 at 00:45
I still don't get why vector doesn't have a pop_front and the fact that I can't sort(list.begin(), list.end())..

- 2,302
- 1
- 13
- 14
-
I think that's because both would be fairly inefficient. You could probably find lots of explanations of why that is on SO or elsewhere. If you really want to use pop_front, use a deque, and if you really want to sort something, it should be an array or vector (or a tree, or...) – Tyler Apr 04 '09 at 05:54
C++ or C/C++? I would say for both the most misunderstood parts are memory management and pointers. The former because people don't free appropriately (too early or not at all!) and the latter because a lot of people just don't "get" pointers (either in the pass by reference "guise" or in general in something like a linked list).

- 26,441
- 7
- 76
- 90
- The difference between pointer (*) and reference (&)
- Accesing multi dimentional arrays using pointers.
- Using * to acess the value of a pointer - i.e. *ptr = 5
- When to release allocated memory.

- 30,292
- 15
- 80
- 129
Why is A[b] the same thing as b[A]?
Ok, not really a COMMON question, but it came up in a class I was teaching once...

- 11,709
- 17
- 81
- 125
-
-
True, but he never said it had to be C++ specific, just a C++ concept... – Brian Postow Feb 19 '09 at 16:17
For some people, difference between inheritance and polymorphism can be a confusing concept.

- 17,009
- 20
- 87
- 142
Very nice resource I can't get tired to promote - C++ Frequently Questioned Answers

- 33,874
- 33
- 95
- 118
-
-
That's a terrible link. Someone put a lot of time in that site just to bash a language. – Brian Neal Feb 18 '09 at 14:29
-
Somebody put a lot of time in that site just to bash a language, and wound up missing the point far too much. It may be fun to read, but you won't learn much from it. – David Thornley Feb 18 '09 at 15:00
-
Totally agree. And he summarizes Marshall Cline's C++ FAQ lite incorrectly all over the place. – Brian Neal Feb 18 '09 at 19:46
-
2the fqa is written in a style that isn't quite serious. it's just downmodding the c++ language with weird reasoning and blatant words. better recommend the FAQ light instead! – Johannes Schaub - litb Feb 18 '09 at 23:31
-
The FQA is true in so many ways. I didn't read all of it but I agree with most of what I read. – hasen Feb 19 '09 at 08:15
-
2This is one of the most distorted and useless C++ links I've ever read, and it's sad that it's posted to SO virtually every time the string "C++" is included in a question. – Daniel Daranas Feb 19 '09 at 08:26
-
1some points he mades in fqa are right i think. but there are so many stupid things he says in that fqa that i would never recommend to read it to anyone oO – Johannes Schaub - litb Feb 19 '09 at 14:19
-
A big one is that the languages are not 100% syntactically compatible. C++ is fully link compatible with C, but some C++ style syntax will generate a complier error in C. Some compilers aren't picky and don't follow the C standard to the letter. The basics of these need to be learned when moving from one language to the other. Note I haven't read the latest C standard, but last I knew this was true.

- 3,003
- 2
- 33
- 37
-
C++ is a superset of C, so of course C++ code isn't going to pass the C compiler... – xan Feb 18 '09 at 15:55
-
Worth noting that sizeof('a') differs in C and C++ (assuming sizeof(int) != 1). This could break compatability for some wacky reason. – strager Feb 18 '09 at 23:41
-
strager: True, and there are a handful other incompatibilities as well. C++ isn't a strict superset of C, although it comes close. – jalf Feb 19 '09 at 00:33
-
-
@xan: C++ is NOT a superset of C, ever since C99 (thank goodness
usually works anyways - boo to MSVC for ignoring C99). – Tom Aug 26 '09 at 00:47