Take the 2-minute tour ×
Stack Overflow is a question and answer site for professional and enthusiast programmers. It's 100% free, no registration required.

Most opinions on Stack Overflow seem to voice a similar opinion: C++ is "harder" to use and it is a "bad" choice for a beginner. Speaking as someone who has been learning C++ as a first language, on my own time as a hobby, for a few months, it doesn't seem all that hard. Admittedly, the first time I took a look at pointers and their relationship to raw arrays, the reasoning behind them seemed flimsy. That was before I created my first stack.

In fact, when I look at C# or Java code, it seems restrictive - why should I have to write a class to print "hello world?"

I guess my question is: what exactly (actual features; don't give me broad generalizations, please) makes C++ harder/bad for a beginner, like me? Alternatively, what makes Java/C#/Python etc. easier?

(This question might seem naive, because I might not be familiar with the lower level facilities. I have not messed around with bits/bit shifting or anything like that. I also have not done any GUI/game programming.)


These are some reasons accumulated by the following posts:

  • Relationship between arrays and pointers
    • Pointer arithmetic
    • off by one errors (not C++ exclusive), and no bounds checking
  • Templates
  • Manual memory management
  • code modules (not C++ exclusive)
  • Preprocessor
  • string support not built in

Some solutions to these problems include:

  • Smart pointers for memory management
  • RAII for memory management
  • iterators for off by one errors
  • std::string && std::vector to mitigate the dmg that char* and arr[] cause

Another common complaint seems to be people's insistence on C++ being "C with Classes." I think good programming makes this a moot point, since a good C++ program will avoid procedural programming wherever possible. A good programmer can also avoid the use of the preprocessor where possible (with the exception of module support, where it is a best practice).

Several responses say that C++ is "too large," referring to either built-in facilities or the STL. I think this has less merit because beginners can focus on a small portion of the language to begin with.

Jalf raises an interesting point that C++ is not necessarily hard because of its broad feature range, but because it requires you (there is no option to ignore it) juggle that WHILE learning to actually program. That interpretation is one of the most plausible I've seen yet.

Others so far have raised issue with the unspoken assumption: C++ is harder to learn for beginners. I think it has been pretty hard to learn, but I obviously have nothing else to compare it to. You won't know if your first car handles well until you've been in another. I think it is an understood truth that learning C++ is like learning a manual transmission as your first car. You understand it better later on, but you still end up riding that clutch too much. (It takes courage to ride a metaphor that long, but I did it.)

Common consensus seems to be that once you master C++, mastering any other language is extremely easy (with perhaps the exception of a functional language like F# or Haskell). This seems to be one of the more useful reasons to learn C++ the first time.


Jalf raised some interesting questions about my own knowledge of the language, with this question:

Just for kicks, let's have a few code examples:

int arr[10] = {};
int* p0 = arr + 1; // 1
int* p1 = arr + 10; // 2
int* p2 = arr + 11; // 3
int v0 = arr[11]; // 4

int arr2[5];
int* p3 = arr2 + 2;
int diff = p0 - p3; // 5
float* fp = reinterpret_cast<float*>(p0); // 6

int i = 42;
int j = i++ + ++i; // 7

Which of these lines are legal, and what is the result of them? (Hint: Only three are valid C++, and of those, one of them returns an unspecified value)

My guesses were 1, 5, and 7 were legal. It turns out 1 and 2 are moral and 6 is legal. That was a little bit of a wakeup call as to how intricate my knowledge of pointers are in C++.


Since this question began as defending my choice of C++ as a first language (and, as of right now, my only language), I figured I should update the people who responded on my progress.

My biggest problem with programming, as of right now, is simple: I don't know how to do anything. Sure, I can write a class that is useful to someone else, but I cannot write anything that would be useful to me in any way. I am not sure, however, if that has anything to do with C++ as the first language - I'm wondering if I'm just not built to be a programmer. It's enjoyable (and extremely frustrating at times), but I'm not sure if I could see myself doing this full time in the future.

One thing I dislike about it is that there are too many solutions to the same problem. This is conducive to several different types of programmers, but I don't feel like I fit the mold of any of them. I think this IS partly C++'s fault, but I could not tell you how I would feel about another language like Python until I've tried it.

I play tennis in my free time, and then solve sudoku if that or socializing are not options. Both of them have multiple ways to solve problems - if my opponent rushes the net, should I lob or try and hit a cross-court shot that he cannot volley? Both methods have easily visible upsides and downsides (the former being, what if it is not high enough or it goes out? The latter being, what if he tags it for a winner on the cross-court?)

The same is not true in programming. One method that looks absolutely fine to me might be hackish, slow, overly complex, or overly simplistic to another programmer. This, coupled with my lack of time/motivation to continue programming, has kept me from doing more than writing a small amount of code each week.

Can anyone think of a way to motivate me past this stage, or do they think I should just give this hobby up?

share|improve this question

closed as not constructive by Bo Persson, martin clayton, John Saunders, tchrist, Derek Kromm Sep 3 '12 at 3:51

As it currently stands, this question is not a good fit for our Q&A format. We expect answers to be supported by facts, references, or expertise, but this question will likely solicit debate, arguments, polling, or extended discussion. If you feel that this question can be improved and possibly reopened, visit the help center for guidance. If this question can be reworded to fit the rules in the help center, please edit the question.

13  
This is actually a really good question. +1 :) –  jalf Jul 6 '09 at 2:28
6  
BTW, it might be a hard choice but hard doesn't necessarily mean bad. Depending on the passion of the person who's learning (e.g. if s/he's more geek and gadget type rather than algorithm/theory type) it might even be a better choice –  Mehrdad Afshari Jul 6 '09 at 2:30
7  
I would argue that even for the worst geek, a better approach would still be to learn a simpler language first, and then C++ afterwards. But yeah, you can certainly start out with C++. Plenty of people have done just that. –  jalf Jul 6 '09 at 2:39

31 Answers 31

up vote 109 down vote accepted

Speaking as someone who has been learning C++ as a first language, on my own time as a hobby, for a few months, it doesn't seem all that hard

Well, you could have learned another language in a week. ;)

But more importantly, how many subtle bugs do you think your stack contains? It's not hard to write something that a C++ compiler will accept. With a bit of effort, you can even make the resulting program seemingly behave as you want. But there will almost certainly still be countless subtle but critical bugs. Of course I can't pinpoint them without seeing some of your code, but I'm willing to bet they're there.

You're right, C# and Java are restrictive. Which is a blessing and a curse. In some ways it is a pain (like you say, having to create a class for a simple "hello world" is silly, although it makes less difference for larger programs - other languages don't require the class though), but the advantage to it is that in being more restrictive, the compiler is able to catch a huge number of errors that in C++ would have gone undetected until you ran the program. Or perhaps until someone else ran the program on a different computer, on the first monday in May. The problem with C++ is that bugs become hugely unpredictable.

C++ is a huge language, and learning all the subtleties of it takes forever, but that's not the reason it's a bad beginners language (if that was all, beginners could just focus on a small subset of the language initially). The real problem is that it is extremely difficult to get right.

And simply that when you're learning programming, the important part is really language-agnostic. Learning to express yourself in code, breaking any problem down into something that can be expressed in terms of a programming language, that's the important skill. But C++ forces you to learn that while also juggling a very complex language, where you also have to figure out pointers, manual memory management, deal with out-of-bounds array accesses, cryptic template compile errors, memory leaks, more memory leaks and countless instances of undefined behavior. (cases where the compiler accepts the code, but the language standard does not specify any behavior, which means that anything might happen, even if the code seems to work. C++ features a huge number of these cases, whereas most languages try to catch or prevent all such errors at compile-time)

It would typically be far more efficient to focus on one at a time. Start out learning programming in a language that doesn't place too many hurdles in front of you. And then, when you've got a grip on programming in general, you can focus on the intricacies of C++.

(I know that I haven't mentioned many specific features as you requested. The problem is that most of the individual features of C++ are relatively simple (template specializations and pointers tend to trip people up, but they're manageable, at least. Template metaprogramming would probably drive you insane, but that's normal ;)). The problem is all the plumbing in the rest of the language. The many unpredictable errors that only sometimes surface, and only when you run the program on some computers, on a bad day, or the problems you might run into trying to get the constructor, copy constructor, assignment operator and destructor on your class to all work together to ensure no resources are leaked and that the class is always in a valid state.

The problem with C++ is all the things that seem to work.


Just for kicks, let's have a few code examples:

int arr[10] = {};
int* p0 = arr + 1; // 1
int* p1 = arr + 10; // 2
int* p2 = arr + 11; // 3
int v0 = arr[11]; // 4

int arr2[5];
int* p3 = arr2 + 2;
int diff = p0 - p3; // 5
float* fp = reinterpret_cast<float*>(p0); // 6

int i = 42;
int j = i++ + ++i; // 7

Which of these lines are legal, and what is the result of them? (Hint: Only three are valid C++, and of those, one of them returns an unspecified value)

share|improve this answer
11  
You're right, if something goes wrong on the first monday of may, you obviously have a bug. The point is that most languages would have caught this bug at compile-time, or at least throw an exception you do something illegal. A typical example is accessing unallocated memory, for example by reading past the end of an array. Most languages wouldn't allow that. They would throw an exception the moment you do it. C++ doesn't. You can happily write over memory until the OS says stop. Which makes the problem unpredictable and hard to trace. –  jalf Jul 6 '09 at 2:34
8  
1 and 2 are perfectly valid. 6 is legal, but the value of fp is undefined. 5 is bad because you're not allowed to subtract pointers that point to different arrays. 7 is bad because you are not allowed to do more than one modification of a variable (or a modification and a read) in the same statement. There is no rule for which of the two should be evaluated first, or if the input to the second one should be the original i, or the value of i after the first ++ is evaluated. The result is just undefined. You're not allowed to do it. :) –  jalf Jul 6 '09 at 3:30
4  
You should get used to the C++ style casts. They're safer, more noticeable (easier to search for), and easier to understand. The C-style cast does completely different operations depending on which type it's used on. Why would 2 point to arr[11]? arr decays to a pointer to arr[0], so adding 10 gives us arr[10] - or rather, it doesn't, because it gives us the "one past the end pointer", which is allowed to exist (unlike the arr+11 case), but you can't dereference it, so arr[10] isn't allowed. –  jalf Jul 6 '09 at 3:57
20  
No it's not. That's just a one-past-the-end pointer. That's specifically allowed. Of course, you can't dereference it, but you're allowed to point there. Most of the STL would fall apart if this wasn't allowed, as you wouldn't be able to create an end iterator. –  jalf Jul 6 '09 at 14:29
6  
really? You never need to find the distance between two iterators? Or add to an iterator to skip a number of elements? I'd say those are relatively common operations, enough so that the standard lib bothered to define std::distance for the former, and random-access iterators for the latter. –  jalf Jul 6 '09 at 19:48

Restrictive is easier. Both C and C++ lets you shoot yourself in the head (and those around you) at every turn.

That said, I think both C and C++ are fine languages for a beginner, but you really should have someone around to guide you and review your work if it is at all critical. A mentor, if you will.

share|improve this answer
1  
Luckily, I do have that. A game programmer on a forum I frequent is a professional programmer. He is the one who assigns me things I ask about on here (look at my profile for previous questions). My impression is that he is extremely good at his job. I believe he came in third in a game dev competition, and that's how he landed a job at a dev. –  Hooked Jul 6 '09 at 2:18
3  
I am currently studying game design. Be wary what they teach you. Back in The Day game programmers just needed to get the game done and shipped and that was that. Whatever worked and got the job done. So they tend to teach non-standard or bad ways of doing things. Just remember you should always try to do things the standard, cross-anything way. Don't use a raw array because it might be "faster", use a std::vector. Good, standard, elegant design first, optimize last. –  GManNickG Jul 6 '09 at 3:40
2  
He's right. It is true that C/C++ (as in C or C++) let you shoot yourself in the head. It is not true that "C/C++ is a fine language for a beginner") You could argue that they are fine languages, but they're not one language, and they don't really have much in common. –  jalf Jul 6 '09 at 16:19
1  
well C++ is statically typed and C isn't so the superset argument there is somewhat disingenuous... If you are referring to C++ refer to it directly, if you are reffering to C likewise. If you are writing C but doing it in a way that a C++ compiler will accept it then that's about the only time the phrase is really meaningfull (and it's bloody hard for anything non trivial) –  ShuggyCoUk Jul 6 '09 at 16:48

I hate to contribute to this question so late but I think there remains one important thing unsaid.

Languages like C++ are hard to learn “correctly” (whatever that means) and incredibly easy to learn wrongly: as a beginner with no experience, you will cut corners wherever possible and you'll do things contrary to design because you don't understand the reasons behind a (seemingly complex) design.

There's certainly not one right way to program C++ but there are just as certainly a gazillion wrong ways. Even worse, most learning resources out there are incredibly. evil. They are really that bad. They not only encourage bad, erroneous style, they teach it as canon. Declaring main with return type void may be one thing but not freeing resources (properly), not giving base classes virtual destructors, using polymorphic arrays, favouring void* to templates are just some things off the top of my head that most teaching books for C++ get, continually, wrong.

If you're learning C++ without proper guidance, you're easy prey to such dangerous practices and it takes year to unlearn these mechanisms. Having started with BASIC myself, I can testify to the destructive force of bad teaching material. Basically, the first three years of my learning to program were complete waste. Three lost years. Who's giving me a refund?

share|improve this answer
2  
That three years may have been more valuable than you think. Learning to deal with complexity and spaghetti, and seeing first hand how things can deteriorate may have made you much more valuable. I think you should get out your checkbook and send Kemeny and Kurtz sizable gifts. –  Nosredna Jul 30 '09 at 16:09
6  
I don't think it can be over emphasised how much bad practice is taught for C++; and not just idioms that might have been necessary nearly 20 years ago. –  Steve Gilham Jul 30 '09 at 16:23
2  
My favorite in "educational C++ books" is the ever-present "error handling omitted for clarity" comments. Error handling is a pillar of software development and nobody reading those books ever learns to write error handling code. –  André Caron Sep 22 '11 at 13:36

C++ is much harder to learn than python. It is also far more educational.

If you have a willing, competent teacher, I would take the opportunity to learn c++. Once you understand memory management, pointers, strong typing and the like you will be much better equipped for a range of programming.

It's like learning to drive, if you learn using a stick shift then an automatic is easy. If you learn to drive on a automatic, driving a stick shift is a nightmare.

See Joel's article for his viewpoint on Java schools. Many of the same things apply.

The flip side is, for most of the things that you want to program, c++ is not the best choice. For web apps, use .net, python, ruby etc. For windows desktop apps, use delphi or .net etc. But if you know c++, then the others are easy to pick up.

share|improve this answer
21  
I find the assertion "C++ is far mode educational" to be very dubious. It depends what you want to focus on. The big problem with C++ (and in lesser degree C) is that it forces you to focus on details, which often do not matter at all. A high level language enables you to focus on API design, etc... C/C++ are awful languages for prototyping for example, so you can't experiment much at first, when you are a beginner. I agree that you need at some point to know about one low level language, but I don't think Joel's point is that it should be your first. –  David Cournapeau Jul 14 '09 at 15:13
2  
as a C++ programmer, I agree with David. There are plenty of things in C or C++ that are worth learning, but it's mostly a distraction to a beginning programmer. It's something you'd benefit from learning as your second or third language, perhaps, but no point in starting with it. –  jalf Jul 31 '09 at 14:44

I started with C++ and till now it is my language of choice in college, really :)

For me, I had a really good professor who chose C++ over python, and I would thank him if I could see him again. It took me one week to catch up with Java(the language) and understand why a lot Java programmers in my college till now they don't know that comparing two strings using == is wrong!

C++ is a language, it is not the library, the compiler, nor the IDE. It is a lot much harder to explain to a new comer that these things are not the same. Unlike other languages, they come usually in one package.

Otherwise, C++ is really a fine tool if you give it your effort.

share|improve this answer
4  
It is a great point that once you know C++, learning higher level languages is easy. C++ --> Java is simple. Java --> C++ isn't even always possible. –  Steve Rowe Jul 6 '09 at 6:35
9  
Why wouldn't Java -> C++ be possible? Once you know another language, C++ becomes quite a bit easier, just like other languages become easier once you know C++. C++ doesn't have any magic special status there, it's simply the fact that if you know another language, you've already learned programming, so the hard part is over. Now you just have to learn the quirks of a new language. –  jalf Jul 6 '09 at 11:51
3  
I believe == compares the strings' memory address, not the value contained. It's been a few years since I worked in Java, am I right? –  NickSentowski Jul 6 '09 at 19:25
1  
@BrendanLong: I find it really ironic when people say of only-Java programmers that they "don't understand pointers". That's all they've ever used. If there's one thing they don't understand, it's the concept of local scope (e.g. automatic immediate release of local variables and how to build your code to put lots of stuff on the stack). –  André Caron Sep 22 '11 at 13:40

Memory management

C++ doesn't have garbage collection. It was designed for speed and garbage collection entails a certain amount of background overhead. In C++ you have to manually free memory after you are done. It's not just a mere inconvenience or annoyance, either. Often this just means you have to remember to put a delete at the bottom of your function to match the new at the top. No big deal there.

The problem is when an object's lifetime doesn't line up nicely with any one function call and spans call boundaries. One example of this is when you have a function like gets() which needs to work with a buffer of indeterminate size. You then have several not-so-great solutions, including: (1) take a length parameter like fgets(); (2) allocate memory dynamically and rely on the caller to free it later.

An even more annoying pattern, though, is when an object has indeterminate lifetime, or indeterminate ownership. Say you add an object to several collections so its ownership is shared by all. Whoever owns it last is responsible for cleanup. This situation stinks and generally involves injecting shared_ptr<>s and the like into your code. Or in lots of older pre-boost C++ code, it meant added reference counters to your classes or hacking together a poor man's garbage collector.

Header files

Splitting up declarations and definitions was a necessity 20+ years ago with the incremental compilers and tight resource requirements that existed then. They are completely unnecessary these days and in fact lead to several migraine-strength headaches, vis-à-vis: (1) dynamic Makefile dependency generation; (2) painfully slow build times; (3) unnecessary code duplication.

Templates

Templates are ridiculously complicated. Error messages when they fail are nigh on unreadable. They're so powerful they are actually Turing complete, meaning you can write full programs just using templates and have the programs "run" when you compile your code. Java and C# figured out how to do generics without the C++ template nastiness.

Preprocessor macros

The same thing goes for the preprocessor. Macros can do amazing things but lead to amazingly unreadable code. And it is just oh-so-tempting to throw a little magical macro dust on your code. "Hey, I could just write a little CATCH() macro to make catching exceptions and printing an error message easier..."

Java decided to just ditch the preprocessor entirely. C# was a little less hateful and kept conditional compilation (#ifdef and the like) but threw out macros, which is really all anybody wanted.

share|improve this answer
2  
To date, I have only developed for personal use on a windows platform, and the use of const seems to mitigate the need for macros. Templates are hard, but as far as I know it's just compile time polymorphism, so i could just rewrite the same function a few times to support my needs if I really couldn't get my head around the templates. As for your first example: I don't understand what "ownership" means. Would you extrapolate? –  Hooked Jul 6 '09 at 2:42
3  
It sounds like you're developing good habits. Kudos. I have no doubt you'll grow into a great non-C++ developer some day. ;-) –  John Kugelman Jul 6 '09 at 2:48
4  
Most memory management can be done by smart pointers. I don't know why John complains about shared_ptr<>, since it's precisely the right thing to use in many cases. Templates will become easier to use. Avoid macros. –  David Thornley Jul 6 '09 at 14:09
4  
Yes, but using smart pointers and RAII gives C++ a unified resource management system, which Java really doesn't have. It's clunkier, but powerful (yes, you can say that about a lot of C++). –  David Thornley Jul 6 '09 at 14:43
3  
C++ a unified resource management system - since there is still no one true smart ptr library I would deny any claim that C++ is unified. That is one of it's great weaknesses. The library was standardized so long after the language that you are doomed to a fragmented user base in this regard. Getting things very close to right first time is really a big deal for the evolution of a language, just look at the pain not having generics from the start causes the collections libraries in 2.0 onwards, so many array returning apis that are messy as hell... –  ShuggyCoUk Jul 6 '09 at 16:52

The main challenge to learning C++ arises from the fact that the language provides constructs and features at various levels of abstraction (pointers, references, memory-management, value-semantics, user-defined types, object-oriented, generic, functional, meta-programming) that are intended to support not just one, but multiple paradigms of programming. In addition, some of those constructs behave non-intuitively (lack of automatic virtual destructors in classes that are inherited) and inconsistently (such as initialization) - mostly because of the constraint of having to design those features with "C" compatibility in mind - in addition, many constructs don't protect you from "absentminded" behaviors if you operate at the "wrong" level of abstraction.

There are some really good parts to C++, and some really bad parts to C++ - you can write some really simple code in C++ and some really cryptic code - but this is not unique to C++ by any means. You can say the same about Java, ruby, javascript, perl, lisp etc. But C++ is a much larger language than those others - therefore it tends to have many more bad parts, but then it also has many more good parts.

I will admit, modern C++ code does tend to get a little too verbose, and some of the error messages are needlessly cryptic, but the use of auto, concepts and lambdas in C++0x will greatly simplify those issues.

There is also the issue of reputation - in its early days, C++ implementations did not have adequate library support - and some would claim that even in spite of boost.org, the libraries are still inadequate (though improving daily) - without the proper use of adequate libraries, one might be forced to have to deal with memory management and other low-level concepts - the debugging of which may indeed scar someone irreparably - such a reputation is not easily shed - especially if there are technologies out there (ruby, python, java) that are specialized enough (i.e. not designed to manipulate demanding or resource-intensive systems) that they insulate programmers from concerns that may not be relevant to the domain for which they are designing solutions.

And it is worth mentioning that C++ is usually not taught well. Many of the older books start teaching C++ with raw-pointers and character arrays (instead of smart_pointers, strings, vectors), along with all their technicalities and low-level details that are usually unnecessary and irrelevant at the beginner level. There are some really good books out there and if one starts with those, I would imagine they would have a very different experience than someone who uses a book that starts out describing native-pointers and arrays before string and vector.

share|improve this answer

Though C++ might be "harder" than other languages like Java or a scripting language like Python or Perl, "harder" != "bad". Learning C++ kind of forces you to learn how a computer actually works, particularly memory management. For instance, I do not know how you would explain the difference between passing by value and passing by reference without a primer on how memory works. Thus, learning C++ teaches you a lot more than just the language itself. It in a way forces you to learn concepts that will be useful in any language (like why "string" == "string" is wrong). I agree with jeffamaphone when he says that C++ lets you shoot you in the foot, but shooting yourself in the foot (figuratively speaking) I think makes you learn.

PLUS, the biggest thing that shoots you in the foot is pointers, and you don't even need to get into that right off the bat. You can learn things like loops, functions, classes, templates, etc and not touch it. I learned C++ for a year before ever diving into pointers. Then when I learned it, again, I was forced to learn how memory worked without having a garbage collector to hold my hand. Sure, it was "hard", but I learned from it.

I learned C++ first and I think it really got me grounded in good programming. If you're not trying to be a programmer, then learning some other language is fine. But, if you really want to learn how to program, I would always recommend starting with C++ (I would say C as well, but then you miss out on object-oriented programming). Higher level languages will deny you learning experiences that are probably quite critical in the long run.

share|improve this answer

C++ is expert friendly.

This means that it is not a good language for a beginner who wants to get things done now.

However, it is a good language for someone who wants to write software that has high demands, e.g. the .NET JIT compiler or the next Unreal Tournament.

C++ has some features that make programming safer, like const correctness and deterministic destruction.

Contrast the viral nature of the C++ const operator with C# where you have to pass a copy of an array to the outside if you want to preserve encapsulation.

I suspect that many bad C++ experiences come from people that write C++ like C with classes. If you are using the new operator outside a ctor, printf or malloc you are probably on the wrong track.

What makes C# better for most is not the GC or the OO features, but the base class library.

share|improve this answer
1  
Things like XML, Web Services and GUI don't really have good solutions in C++. I agree though that the things that are covered in boost and STL are often more powerful than you'll find elsewhere. –  Hans Malherbe Jul 6 '09 at 20:19

Specific measurable differences compared to java and c#:

I am not in any way suggesting one approach or the other is better simply that they are different and that difference makes one or the other easier to pick up/learn/avoid bugs

Pointers

java/c# No raw pointers (c# none by default and even then very restricted) C++ pointers all over the place.

Pointers are not in simple terms overly complex, but they can rapidly combine in interesting (read hard to understand) different ways and they mean that common errors with them (running off the end of buffers for example) can have poor locality of error. So eventually you hit a bug/crash but that tends not to happen where the bug is, but in some, possible entirely unrelated, other part of the system.

If the code in question is new greenfield development it is possible to avoid many uses of pointers but many third party libraries assume their use.

Bounds checking

As alluded to above, buffer overruns due to a runaway pointer are impossible. As are invalid casts, writing to references which are no longer alive and a host of other possible accidental bugs.

Managed memory

In java you have no control over new whatsoever. It goes on some heap you have no control over (and thus cannot go wrong). You do not have to ensure it is deleted by the correct counterparty (delete/delete[]). In c# there is a slight amount of control (structs/stackalloc) but this is limited to very controlled areas which most c# developers probably never use.
There is no need to pass around the allocator when using templates that need to allocate.

Total reflection/introspection

In the managed languages you can, at runtime, inspect the structure of your entire object graph if desired. Even if a reference is via an object typed variable this doesn't stop you (and more importantly the debugger) knowing exactly what type the instance actually is.

Single inheritance (of implementation)

Multiple inheritance is rarely used and makes the reflection scenarios very complex.

strings are immutable and built in

For all that C++ now has std:string there is a still a vast amount of code out there expecting to deal with c style char pointer strings. The functions for working with these are tersely named, many have dangerous buffer overflows associated with them, some expect you to include the trailing null, others not.

The immutable strings in c# and java prevent many of these bugs ever happening and avoid many forms of memory leaks

standard method naming

C++ tends towards a terser method naming convention, c# and java towards a verbose one. This makes reading code for inexperienced readers considerably simpler.

Definition and declaration in one place

No header files, no confusion of what should go where and the compilation effects associated with it. Forward declarations perfectly legal and the compiler sorts it all out for you. The resulting error message in the simpler languages also tend to be better. The c++ pre-processor is incredibly powerful, but as a result can produce bewildering error messages.

Tooling

The newer statically typed languages tend to be pretty simple to parse robustly even when not fully completed. This makes the advanced IDE functions like intellisense and error highlighting more functional and responsive. Given the large size of modern standard libraries this is often very important to inexperienced developers.
The well structured introspection aspects of them also provide for more flexible design time scenarios.

Primitives

Fixed size integral, floating point, characters, you never have to be aware of your target hardware unless you are using IntPtr.
IEEE FP arithmetic is mandated.
Overflow can be detected automatically.
booleans are very well defined and no casts to/from them are allowed.

Common features built into the language (or Sugar!)

foreach - readable (IMO slightly less so in the java version) and removes off by one errors.
locking - though several of these can promote bad behaviour they are at least standardized.
Absolutely everything can be made to output a textual representation by default.
try/catch/finally simplifies much of the SEH code.

Conclusions

You will note that in many of the examples above c#/java prevents you doing something or only allows you to do it one, highly controlled, way. In this it is simpler to learn. C++, by being more general, has an inevitable additional cognitive load when wanting to do something which could be achieved by more than one available technique.

share|improve this answer
4  
C++ does not in general need raw pointers, and resource allocation with RAII and smart pointers is more general than garbage collection. If you have to deal with existing code that uses pointers and char *, why is it easier to use C# than C++? –  David Thornley Jul 6 '09 at 14:49
1  
If you're dealing with existing code then of course changing to some other language almost always has a big -ve against it. What I'm saying is that I have used loads of supposedly C++ libraries from other vendors where they expect c-style strings. Thus you end up having to know about them (and their pitfalls) –  ShuggyCoUk Jul 6 '09 at 15:16
2  
C++ is more general (Implied in my conclusion). Writing good RAII code is harder than writing something that lets you forget about who is the owner of the result of new. Consider any program X which contains at least one allocation whose lifespan is neither stack nor instance bound. In C++ if you are not to to leak 1) Identify this, 2) wrap all access in a smart_ptr (picking the right one!). You simply don't need to do either of these things in c#/java. That this might be worse for the performance of the app is immaterial to the question in hand which is "why is C++ considered harder" –  ShuggyCoUk Jul 6 '09 at 15:21
1  
The point about the consistency (needing to know which classes require disposal) is a good one but one can point out that, to a beginner this often doesn't matter and the two most common instances of this (Streams on files and database connections) are commonly identified in examples as requiring this. Deterministic disposal of local variables which require dispose would be an interesting addition to c# I think. That said forcing you to think about the usage of a limited resource is not always a bad thing. –  ShuggyCoUk Jul 7 '09 at 12:06
1  
I would say that, on balance, the ratio of memory deallocation code verses resource free code is skewed so far towards the former that, for beginners, the GC aspect wins in terms of ease of learning. Whether this is long term a good thing is a more complex question. –  ShuggyCoUk Jul 7 '09 at 12:08

I think when people are saying C++ is hard, they are thinking that it's hard to master that language to the extent that they feel confident. They reality is that the more you learn about this language, the less you know. There always a better/fancier way in this very same language to re-implement what you have done as long as you do not give up. It's a beast you seem to never be able to kill. Well, the fact is you don't really have to IMHO.

On the other hand, with some other languages like python/C#, you will soon get to the point that you really know the language enough, all that's left is about familiarizing yourself with the library/APIs, and there's not much left to be squeezed inside the language itself; or at least you tend to feel so.

Like you just experienced yourself, if you only learn C++ to get things done in the common way(i.e. like people typically do with other languages ), rather than try to write the best possible code in terms of performance/style etc. C++ is really easy to learn.

another minor point is that, with C++ you need a little low-level thinking like pointers, memory allocation and collection, but that's trivial labor and the gain is great: you lay yourself a solid base for writing performant code.

share|improve this answer

this mainly because you had to consider many other factors other than just the program logic itself when you program in C++. Things like pointers, memory allocations and cleanups are usually nothing to do with the program logic itself but low level machine details.

On the other hand, when you program in Java, C# or Python these details are hidden away from the programmer's view. Therefore, a beginner can just focus on learning the logic behind programming rather than getting scared away by all these complex factors around him/her.

share|improve this answer

I'd say: 1) split declaration/definition This is fairly minor, but a nuisance, the managing of class and function declarations outside of the implementation. Lots of chances for mistakes, especially early on.

2) manual memory management New vs. delete (and the C malloc/free) whereas many of the alternatives do their own garbage collection and cleanup.

3) c vs. c++ Basically: how to write good c++ vs. a mish-mash of C and C++. The "have to write a class for Hello World" is kind of a lame argument; it's much more about how you organize and structure your (useful) program. Part of what makes C++ somewhat ornery is that it is (a) built on top of C, and (b) doesn't prevent you from smushing the two together and cherrypicking what you want. Useful sometimes, but also makes it difficult to understand

4) evolutions in provided libraries that are native to the environment The libraries and classes provided in .NET and Java offer a lot of reuse potential and make rapid and more robust development possible. C++ has a lot of reusable libraries out there (notably boost) but they are generally add-ons and not part of the native environment. With (say) .NET, I know what all .NET developers are going to have available. With C++, that domain is a lot smaller.

share|improve this answer
1  
As for memory management, I think the use of the STL mitigates a lot of this. In any instance where I need to dynamically allocate memory, it seems like the use of std::string or std::vector is a superior choice. –  Hooked Jul 6 '09 at 2:38
1  
but RAII and smart pointers can take care of that. –  jalf Jul 6 '09 at 11:53

It's difficult to build a comprehensive list of "bad things" about C++, but some of the most important to me are :

  • Too big. That makes it harder to learn and most important, to read and maintain.
  • Some relevant things are done "under the hood" and can pass unnoticed if you're not careful (e.g. copy constructors).
  • It's not a strict superset of C (unlike Objective C, for example), which can lead to problems when you try to map previous knowledge from C or just try to port some code.
  • It gives a false impression of safety and "high levelness", which is very dangerous (at least with C you always know that you're walking in a minefield and that keeps you alert).

And of course, there are lots of other languages that usually fit better for the task at hand, C++ tries to be good for everything and that's just impossible.

share|improve this answer

There are already many good answers in this thread. Let me just add that C++ is a very flexible language that does not require (or even encourage) a developer to structure the code in any particular way. That is a blessing for an experienced programmer but a curse for a beginner. You'd better make sure you are learning the language from a good and recent book, or even better have an experienced C++ programer guide you and review your code.

Good luck!

share|improve this answer

Well, there is definitely something to learning the fundamentals, being "hard", and then learning the simplified. Don't get me wrong, I've spent many many years of my life doing Java, and I've built a really nice lifestyle thanks to Java.

But in the end, everything on the computer eventually boils down to C/C++/asm at the lowest levels, and so I hold that it's good to have spent some time down there.

Plus, C++ gives you some job insurance considering many of these other languages are controlled by large companies. For example, everyone is holding their breath to see what Oracle does to Java, and MS has enough power to one day turn C# on its head and no one could do anything about it.

Additionally, it's similar to learning musical instruments: if you start with one that is very difficult, and learn it well, learning to play simpler instruments becomes trivial. (Specifics removed to avoid the flames).

All in all, obviously you're free to do what you want. It's possible to go an entire career (hopefully, given the state of CS education in the US at the moment), in Java, and never have to learn anything else. A guy can make a decent living at it after a number of years.

But let me say that you will never regret the time you spend learning the lower-level languages. It gives great appreciation of the mechanics of how things work, and you don't necessarily get that any other way.

share|improve this answer

Everything is relative. I would say that C++ is easier than C, since it manages memory for you, comes with a bunch of cool containers and makes lots of other things easier:

printf("%d %f %s", a, b, c);

vs

cout << a << ' ' << b << ' ' << c;

But I would also say that Python is easier than C++. It can't do everything C++ can do, but it doesn't try to. It is like learning to drive with bumpercars.

To me, Java and C# are the worst of all worlds. They can't do what C++ does, yet require the ugly syntax.

share|improve this answer
1  
(not related to main question) I'd still use: cout << boost::format("%d %f %s") % a % b % c. Much easier to localize and easier to read when your pattern is more complex. –  liori Jul 30 '09 at 16:15
1  
totally awesome for propping c/python and slamming java/c#. –  Matt Joiner Nov 2 '09 at 15:35

Here's a stream-of-consciousness list:

The compile/run cycle takes longer than interpreted languages like Python, Perl or Ruby. Static types are not usually known to non-programmers. The Standard Template Library and other template-based language facilities use templates, which is another barrier with a new syntax along with unintuitive compiler errors. There are some tricks to inheritance, including default constructors, multiple inheritance and virtual destructors. The concept and syntax of pointers is a hard thing for new people to learn. Memory management is important and non-trivial to learn, and it's important to do if you do serious programming with other people who write C++. Error messages can be opaque and difficult to understand, both from the compiler and at run-time.

The bottom line is that C++ has a lot of domain-specific knowledge that you just need to have in order to understand the programs that people write, and that's a barrier to learning. Languages like Python and Ruby are much simpler, which means that you can more quickly get to the point where you're learning more general programming concepts and less specific knowledge about a language.

share|improve this answer

Actually, I think it's easier and perhaps a preferred way to learn (when learning just the basics of programming in general). But since it can become a handful awful fast ...just take it slow. None of this "learn to be a master coder in 10 days" crap.

share|improve this answer

It's actually GOOD to learn C (and C++, I suppose...), but there are a lot of gotchas.

Most of them revolve around these three things: Strings (or lack thereof), arrays, and memory allocation/deallocation. These three things probably constitute 99% of the serious bugs in C & C++ code.

I don't want to go into the details, but I'll refer you to a good companion book. If you're going to learn C/C++ for serious development--and regardless of platform--I strongly recommend picking up a copy of Secure Coding in C & C++. I think this is a book every C coder should have. Doubly so, if learning C after having developed on a managed language like Java or C#.

Edit: The one other "gotcha" of C/C++ are the libraries. If you want to do anything serious, chances are the library is custom to the platform. For example, you'd be using the Win32 API (or ATL/MFC/WTL for C++) extensively for just about any kind of Windows development.

share|improve this answer

I don't know what you are working on, but be aware that as a beginner there is a good chance that the problems you are tackling aren't hard or subtle. In that world almost any of the common languages would allow you to write perfectly nice solutions.

C++ supports multiple styles of programming: procedural, OO, generics. In skilled hands I'm sure this is wonderful, but beginners often find it confusing. In contrast, one of the design goals of Python is that for most problem there should be a correct, and fairly obvious 'Pythonic' way of handling it. There may be many better and subtler ways of tackling it, but the obvious way shouldn't lead the user too far astray. In C++ there may be 100 obvious ways of tackling a problem, all of which seem correct, but 87 of which lead to subtle problems.

I'd suggest that you take a look at Scott Meyer's "Effective C++" books. His examples often start with simple class designs that seem perfectly reasonable, and he gradually reveals the subtle problems they cause. You might also try C++ Frequently Questioned Answers. If you can understand his objections to C++ and counter them you are a pretty sophisticated developer.

share|improve this answer
2  
Would upvote for the Meyer's reference, would downvote for the FQA reference. As a result, I'm not doing either. –  David Thornley Jul 6 '09 at 14:44

It's the terms "a beginner" vs "a beginner, like me" that's the trick to this question. Since your finding C++ easy to learn, then you obviously get "it" and so it's and ideal language for a "beginners like you".

When people make a sweeping statement that "Java/C# is easier to teach beginners than C++" they are actually thinking about beginners who are "not like you", and would struggle with "C++". They're also going to struggle with Java and C#, but suprisingly, not as much.

I love C++ as much as I love Java and C#. If I was to give one bit of advice when learning a new language is to avoid the trap of "this is how I did this in language A, so how does that translate into language B" but rather, try to come to terms with the underlying philosophy that that language was designed with so that you can use that language the way it was intended.

So when you ask "why do I have to have to have a class just to print hello world?" I would counter ask "why do I have a function main just to print hellow world?". Why is my program not simply:

Print Hello World!

Using this approach, I've never met a language I didn't like (with the possible exception of R-Base 5000).

Some interesting points from some of the other comments on this page:

C++ doesn't have good string support: Well maybe not built in, but there are a ton of good C++ string classes out there.

C# doesn't have pointers: Actually it does, along with all out favourite operators from c/c++ including ->, & and *. Let's face it, there are just some Win API calls that can't be made without resorting to pointers. The difference is that I get to lock these away in special routines I've marked as "unsafe" (a rather poor choice of keyword) limiting any impact they have. I'd bet that 90% of C# programmers have no idea about this, and that's because 99% you don't need to know in C#.

C++ is more efficient and lower level: We'll not really. The early days of 'c' were closer, but these days the compilers generatre so much more assembly than you would ever expect to see. If you want that level of efficiency and control, then learn assembler. At least most C++ languages allow us to write assembly in line so we can take control of that if we want to. But don't get into the "performance is everything" trap. I've seen programmers agonise over things like which is faster, a switch or an if, or worse, sacrafice readability of code for what they think will save a few CPU cycles. Twenty years ago with low end resources I'd probably agree with them. Today, with giga-cpu-cycles going to waste every second, most programs will benefit from a modern productive language that makes the most of the one resource that gets more expensive every day, but whoes capability remains very much the same as it did 20 years ago, the programmer.

From someone who occasionally has to select a language to teach beginners my two biggest concerns are:

i) The squiggly brackets and the sometimes you need a semi-colon and sometimes you don't syntax. This equally applies to Java and C# of course, and is one of the reasons why Pascal and Basic style languages are popular with beginners.

ii) The big one though is that while every language has "subtle" errors, C++ has far more than Java and C#. Inevitably beginners can't get their program to work because of an error they find hard to track down. Besides being frustrating, it burns valuable time that they could be using to learn more. Some relish these, I used to think it was like solving a logic puzzle or a Sherlock Holmes mystery, but others who would otherwise still be reasonable devlopers begin to despise the language, and loose the point that was being taught.

It might be because an int wasn't initialised, or it's because an integer was confused with a pointer or a handle or a pointer to a handle, or a pointer to a pointer, or because a conditional expression yielded an integer value but should have been a boolean. It doesn't really matter which of these it is. It's simply that there are so many different ones that can happen.

But C++ is a great language and the last thing I would ever want to do is discourage anyone from learning it.

share|improve this answer

First of all, I wouldn't call it a BAD choice... That would be like saying that learning to drive a car with manual gear is a bad choice.

C++ is considered harder to use because when programming in C++, one has to take many things into consideration - Memory management for instance: If you program in Garbage collected languages, you wouldn't have to worry about memory allocation and disposal, but on the other hand, the control is taken away from you.

C++ is a powerful language, in which you can have full control over you code execution, and achieve great performance, but many of the features which can be taken for granted in Java or C#, aren't so in C++, and you'll have to write your own classes.

In summary, it's obvious that driving an automatic gear is easier, but race drivers drive cars with manual gear...

share|improve this answer

Because once you are a beginner in C++ you also have to be a beginner with compilers, bitmasks, memory layout and management, vanilla C (that's what it comes down to), some asm (to understand what is actually going on), linkers (how else will your program do anything useful?) and in general to the way computer manages programs as opposed to how a human manages them. It's 80 percent "working around the system" and 20 percent learning to program in the traditional sense. Basically you jettison yourself into the vast ocean of warts of modern computing all at once. Dunno if that's best for a beginner.

share|improve this answer

In fact, when I look at C# or Java code, it seems restrictive - why should I have to write a class to print "hello world?"

That's not restrictive at all. It's just a bit of extra boilerplate; it doesn't stop you doing anything at all.

In fact, it's not really true to say that you have to "write a class" in any creative sense. You don't have to think about it at all, and a decent IDE generates it for you anyway.

There are genuine ways in which Java and C# restrict you, but only from things like random access to the whole of memory or unchecked array access (same thing), that are generally only needed in realtime, embedded or kernel-mode programming, and not even always then.

(And in fact C# has an unsafe block feature in which you can do those things, so it's not really restricted at all, although it's best to avoid using them anyway.)

Once you've overcome the challenging hurdle (!) of dealing with:

public class App
{
    public static void Main(string[] args)
    {

    }
}

You should find that a lot of benefits begin to become apparent - especially in C#, which has a number of great features that Java lacks.

These are some of the things I've come to happily rely on since adopting C#:

  • rich reflection at runtime
  • runtime-type safety with no holes (disallowing casting between unrelated types)
  • dynamic libraries as a built-in concept
  • built-in garbage collection
  • bounds-checking at every level
  • a vast ecosystem of ready-to-use libraries designed to take advantage of all the above

And those are just the things that Java also has. In C# the functional style enabled by lambdas and iterator methods is like a different world of power and expressiveness altogether.

share|improve this answer
2  
But in C++ you have "what is an include file?" and "What does << do"? and "What does :: mean?" And in any case, if a language makes Hello world easy (and I don't think C++ does), but everything else hard, that's not a great criterion to judge it by. –  Daniel Earwicker Jul 6 '09 at 21:38

Any language with overloadable functions and operators is going to be harder to learn than a language without these features. Pointers and addresses are a known learning difficulty, plus there is a similar (but different) notation for references.

Code snippets in C++ often cannot understood until at least several header files are also read, and these need to be found- code navigation skills are always a barrier to learning for new programmers.

share|improve this answer
2  
Java and C# both have overloadable functions, C# has overloadable operators. –  Daniel Earwicker Jul 6 '09 at 14:26

I started with C++ and I don't see it as a bad thing either. Nor particularly hard. You don't HAVE to "write" a class to do a hello world (while console applications are set up with the "static class Program" by default, that doesn't really make it "writing a class", if that makes sense). I bet you don't even need to do that to actually get the program to work either, but I have never tried.

What makes C# "easier" I think is just the nature behind how it is set up and how much more is done for the programmer in terms of memory and management.

share|improve this answer

I really like C++. It was my second language, and my first real language. I consider it my primary language(while knowing that there are Masters of C++, and I am not a master).

It's very complex, however, and if you dabble in the more complex areas while learning how to "think programming", you're going to have your feet cut from under you - repeatedly. There will be bugs, and you won't know why, or how to find out why, because you're a newbie.

I recommend Common Lisp for a first language, personally.

share|improve this answer

C++ is not only a OOP language but a multiple paradigm language. A C program (imperative) usually compiles without problems with a C++ compiler. You can do Meta-programming of you walk the extra mile and use templates.

So YOU have to decide what purpose the language is used for. New programming languages (like C# or Java) are designed with a specific purpose in mind, like "work well with .NET" or "easy to learn and use". For C++ it is the other way round. NOT the language determines what it is used for but YOU decide what you use it for.

It does also does not run inside a virtual machine so you have to stick very close to the underlying platform you compile on.

share|improve this answer

Not the answer you're looking for? Browse other questions tagged or ask your own question.