6
$\begingroup$

I am going to teach a C++ course to students who already know Java. From answers to my previous question, I learned that C++ is substantially harder to master than Java, particularly because of the need to manually manage memory allocation. Thus, I expect my students to ask:

Why do we need to study C++ at all? Why not use only Java?

Two general answers are:

  • Because C++ is faster (but I am not sure the difference is substantial enough)
  • Because C++ is already used in many companies where you might work in the future.

But I am looking for a more convincing answer. In particular:

  • In what kind of applications is C++ considered a better choice than Java?
  • In what parts of the software industry is C++ used more than Java?
$\endgroup$
  • 1
    $\begingroup$ Are you familiar with C++? In case your're not the better question would be: what other programming Language should we learn beside Java? Eg: the automobile industry is using plain C because C++ didn't hold its promises regarding speed (either developing nor execution time) and safety. $\endgroup$ – Timothy Truckle Jan 13 '18 at 17:07
  • $\begingroup$ After some thinking I believe you cannot get a good answer from here because we all live in our filter bubble. I personally know nobody doing C++ for a living. Some other might know only people coding it and nothing else. So what you're asking for is a research about the current importance of C++ in the current industry which most likely non of us has done (yet)... $\endgroup$ – Timothy Truckle Jan 13 '18 at 17:45
  • 3
    $\begingroup$ It is not that C++ is fast (to make if fast all sorts of manual optimisations need to be done), but that Java is slow. Java is slow because of virtual machine, and because of memory layout. e.g. for a linked list, it is impossible in java to ensure that the payload is proximate to the linked list, therefore a java implementation will suffer many more cache misses. Another thing that java does not have is proper tail call optimisation. However while it is easy to list short comings in Java, I would find it impossible to recommend C++. The only time to use C++, is to make a contract last forever $\endgroup$ – ctrl-alt-delor Jan 14 '18 at 15:28
  • 1
    $\begingroup$ @ctrl-alt-delor this simply isn't true. If you want to layout your arrays in memory manually in Java, then you can (it's been almost 15 years since this feature - mem-mgmt - was added to the main Java implementation). At the same time, JVM's are positively encouraged to recompile code (for 20 years now!) to fix problems like this. They tend to be pretty good at it. $\endgroup$ – user31 Jan 15 '18 at 0:15
  • 1
    $\begingroup$ Because one day you will want to get a job at a company that doesn't use Java, so we're going to start exposing you to new languages now, so you won't be stuck thinking in Java? $\endgroup$ – user253751 Jan 15 '18 at 3:11
2
$\begingroup$

There are a few places C++ (or C, or rust or ...) is more useful than Java[1] because C++ does (what Rust likes to call) "zero cost abstractions". The idea is that C++ gives you the power to be as low level as you want to get, and at the same time as high level as you want to go.

  1. Real Time. Note, I didn't say fast. real-time doesn't always mean fast. Technically, a real-time program could actually be slower than one which is not "real-time".

The main focus of real time is that there should be no pauses longer than X between event firings. So if you have a self-driving car doing something like like:

while (true){
    MyType currentPos = getPos();
    MyType newPos = doCalculationsOnPos(currentPos);
    adjustWheel(newPos);
}

You should know for a fact that you will adjust your steering wheel every X ms or your car can crash. In C++ (and a few other languages, like C, asm, or rust) you can tell during compile time how long will it take to run this loop. Now what will happen in Java (a garbage-collected language)?

while (true){
   MyType currentPos = getPos();
   System.gc();
   MyType newPos = doCalculationsOnPos(currentPos);
   System.gc();
   adjustWheel(newPos);
}

The problem here is that you have no idea how long System.gc() will decide to take. And this isn't just useful in robotics (cars, airplanes, or rockets), it's useful in prosaic cases such as writing a time server [2].

  1. Interfaceable - If you need to write libraries, you'll have to do it in C++ (or C, Rust, Pascal ...). The reason is that, as above, C++ does zero-cost abstractions.

So for example, code like the below can be called like a C function (which is the standard function interface in pretty much all OSs these days) of the same name. So you can use this function in Python, in Rust, C, Java, C#, Go, you name it.

extern "C"
int hi(int p){
    typeO* a = new typeO(p)
    int returnVal = a.doWork();
    delete a;
    return returnVal;
}
  1. Low level code - In C++ you can control how and where memory is stored - is it stored in the stack or in the heap. How would you write a Java memory allocater when you don't have a heap to put things in?

[1]. Yes, there are AOT compilers written for Java, and there actually was an 0OS written in Java. But you'll need a lot more work bootstrapping the Java environment than a C++ environment. But more importantly, since those solutions are fairly niche (and, at times, not FOSS or even gratis), the community around them is tiny. So, yes, you can compile java to exe (and have been able to do so for a while), but one of the reason that some of the Java community's moved to Go was precisely because Go compiles to a static binary, and the rest were eagerly awaiting AOT compilation.

[2]. Yes, he picked Go (which is a GC language), but it can be turned off, turning Go into a real-time language. The thing is that an ntp server needs to be real time for only a short while. If, though, you need it off all the time, Go won't work for you as memory will grow until you clean up garbage, turning off all real-time guarantees.

$\endgroup$
  • $\begingroup$ This is very interesting. Indeed I can focus my course on real-time applications and libraries that should link with other languages. $\endgroup$ – Erel Segal-Halevi Jan 20 '18 at 17:25
8
$\begingroup$

I think you're having trouble justifying the study of C++ because of the way that you're thinking about it. If you are aiming towards the practical benefits, then you immediately get to the following trap: neither you nor your students has any idea what languages they will work with in the future, so neither you nor your students have any idea what languages would be the most practical to learn. There are no good answers when you begin this way, and the motivations will always seem to fall a bit flat.

I might steer the students (and you!) towards a slightly different model of thinking about benefits here. What foundational ideas about programming and Computer Science are easier to grasp in C++ than in Java? These foundational ideas will important later, regardless of the development environment, because they are the building blocks of computational thinking.

When we teach CS, we are concept-focused and language agnostic.

This lens also provides you with the beginnings of a map through the topic itself. You can quickly sketch out a curriculum at this point, which is best done backwards:

  1. What are the most important concepts that you want the students to learn?

Fair warning: I am not a C++ programmer! There may well be more important topics than these to get into, but I know that C++ gives students an opportunity to learn about pointers, pointer arithmetic, and memory management. You could also get into casting and bit-operations, which forces the students to learn about data representation. Each of these concepts are fundamental to computers, and much harder to learn about in Java, which abstracts them away.

Selling the language to the students is now a comparatively easier task. You're using C++ because you get to show them some very cool things about how computers really work.

The best time to do such selling is on the first day. By explaining #1 to them at the beginning, you alter their motivation going forward. They want to do well on the tasks you've outlined not only because it gets them a better grade, but because they are also mastering deep, important concepts that will help them understand computational thinking. Computational thinking will help them regardless of what they do in the future. Heck, they could leave the field entirely; they would still have mastered a rich and powerful tool-set for thinking about problems, wherever they go.

Now we get to the planning portion:

  1. What is the most logical ordering of those concepts?
  2. How will you (and the students!) know that the concepts have been learned? This could be some combination of projects and assessments.

I've grouped these together because they are a little interdependent. Sometimes step 3 will cause you to go back and modify the order in step 2, but these two steps are how you arrive at a well-organized semester. The best tasks for #3 are also rich and interesting in their own right. (One resource I could recommend for help finding great, motivating tasks for a given concept is this very site.)

It is extremely important that you really get a good answer for #3. If you've done these three steps well, then the projects and assessments will now be sufficient to prove that the students understand the material. If you've truly answered #3, and you have total trust in that, then it frees you up to spend the entire course doing one thing:

  1. Prepare your students to do really well on those tasks.

The reason that #4 is so important is because of the social dynamic that results. You really want your students to feel like you're on their side, pulling for the same team. And if your goal, every day, is to help them master the material, then they will be able to see that you are putting tremendous effort into trying to help them. And there are also benefits to you here; as a relatively beginner teacher (who will certainly make some mistakes along the way!), having students who are willing to cut you a little slack can make your life a lot easier as well.

Now we have a strong course structure! Tell the students about the cool concepts they will be learning, and tell them that C++ is a great language to focus in on these concepts. Map out the order of the concepts that you'll be covering and tell them about the projects, tests, etc. Then come in every day, and focus in a rather laser-like way on making sure that the students are well prepared for the important tasks that you've designed.

(Apologies for the length of this response. I wasn't trying to write a book chapter, but I am leaving the information in in the hopes that you will find it very helpful!)

$\endgroup$
  • 1
    $\begingroup$ "C++ gives students an opportunity to learn about pointers, pointer arithmetic, and memory management. You could also get into casting and bit-operations, which forces the students to learn about data representation. " These are concepts of plain C. You don't need C++ to demonstrate them. But Yes, it's hard to get a pure C compiler (for free) these days... $\endgroup$ – Timothy Truckle Jan 14 '18 at 12:11
  • $\begingroup$ @TimothyTruckle Fair enough :) I mentioned I was not a C++ programmer. Most of what I teach is in Java, so those concepts were guesses on my part. Buffy's answer is undoubtedly far better in terms of what concepts should probably be focused on. My point to OP was more about how to justify (and set up) a class for students. $\endgroup$ – Ben I. Jan 14 '18 at 14:49
  • $\begingroup$ In my experience, people start to really understand programming after they learn their third language. C++ is sufficiently similar to java that there is carryover, but different enough to increase the breadth and depth of their skills. $\endgroup$ – pojo-guy Jan 14 '18 at 19:36
  • $\begingroup$ @TimothyTruckle, GCC, with the right command-line options, can be made to obey and enforce any of several different versions of the C standard. (gcc.gnu.org/onlinedocs/gcc/Standards.html#Standards.) $\endgroup$ – Solomon Slow Jan 15 '18 at 2:40
  • $\begingroup$ @TimothyTruckle What's wrong with GCC or LLVM, the quintessential free C compilers? $\endgroup$ – user253751 Jan 15 '18 at 3:16
5
$\begingroup$

There are many reasons for wanting to learn a new language, whether C++ or something else. I'll try to make this general enough to address Timothy Truckle's concerns in a comment, but also the questioner's direct question.

If you are a scholar you learn a new language because it gives you some additional perspective on programming that the languages you already know don't possess. For example, some major programming paradigms are imperative, object-oriented, functional, and logic. The scholar will want to know at least the essence of a language from each group.

If you are a prospective employee (such as a student) you probably want to know several languages, even if they are quite similar (ruby, python) because it might give you an edge in getting a job.

If you are already employed you use the language of the group you are with, even COBOL. Occasionally a group will want to change languages and when this happens, knowing the new language will, hopefully, prevent your getting replaced.

If you simply have a program to write, use the language you know best unless (a) it is inappropriate to the task or (b) you want to wear the scholar hat for a while.

Sometimes you choose a language for no other reason than the set of libraries that it is offered with. Those libraries may do most of the work for you in the current task, so don't underestimate the importance of this.

As to the question of C++ vs Java, they are similar on the surface, but have deep differences. Java is a fairly pure OO language, though there have been improvements since it was introduced. C++, on the other hand is a true multi-paradigm language. It is not, however, an OO language, strictly speaking, though it can be programmed that way. It is much stronger as a Data Abstraction language than an OO language, but you need to become familiar with the Standard Template Library to be able to clearly see the difference between that and OO.

From the scholar's standpoint, the great thing about Java, and the reason it is a good first language, is that it takes many decisions and concerns out of the hands of the application programmer and handles them automatically. The biggest of these is memory management, especially the heap. Java's garbage collector means that you needn't concern yourself with the lifetime of objects except in extreme cases. These cases don't arise for beginners, and when they do, Java is not likely to be the best language (billions of objects existing simultaneously, for example).

Still from the standpoint of the scholar, programming in C++ will force you to think at a more detailed level. This isn't ideal for the beginner, but every master programmer needs to do the nitty-gritty at some point, and C++ forces you there.

Java is a much more abstract language. For example, it has only single inheritance, so using formal interfaces is much more important there. The "meaning" of code can be expressed in Java Docs for interfaces rather than in the code itself (though there is danger there, of course). If you program wisely in Java those Java Docs on the Interfaces are likely all of the "comments" that your code needs.

Multiple inheritance in C++ holds many pitfalls, that are overcome with attention to detail and with a level of planning that you don't need in Java, since that alternative isn't available. Combining two superclasses as parents of a subclass can lead to poor design if not done wisely. That isn't a stroke against C++ but a warning that the programmer needs to develop additional skills to avoid pitfalls.

Other things in C++ are more complex than in Java. Visibility, for example, and especially friend classes. Also includes, namespaces, and some lower-level things such as structs. Again, it isn't that this is bad in C++ but the programmer needs to learn how to handle a greater range of detail than in a more abstract language or in a single paradigm language. Learning how to deal with that, and learning the tools that help you do it is valuable.

However, to say that C++ is more efficient than Java is wrong in general, though it may be correct in some situations. Compilers have come a long way in recent years and the efficiency of code is dependent on the quality of the compiler. In particular, if a language must be used at a detail level then the compiler has less opportunity for optimization than if it is used at a more abstract level. If my program describes how to do something it is quite different than if it describes what must be done. In the latter case, the compiler may be better able to come up with the how to than you are. If you describe the how to itself in your program, the compiler may have no option than to plod along with the steps you chose even when there might be a better path to the goal. Functional and Logic languages were once thought inefficient, but they need not be. It was a result of the level of sophistication of translation available at the time.

To conclude, C++ is a good choice to follow Java as it will reveal a level of detail that the Java programmer didn't previously need to contend with. Even if you only use C++ as a better C you will learn a lot.

But learning a language, like Prolog, say, in a completely different family will also teach you things that are quite different, not just deeper, than what you already know - orthogonal dimensions.

$\endgroup$
  • $\begingroup$ Overall very good, I'd add that c++ implementations of low level code like the guts of xalan/xerces xml libraries tend to be twice as fast as their java counterparts. On the other hand there are certainly places where java is comparable in throughput to c++. You might point out that the jvm is written in c/c++ $\endgroup$ – pojo-guy Jan 14 '18 at 19:32
1
$\begingroup$

I'm a multi-platform programmer who has spent many years using C++.

In the last 5 years that has included:

  • The Realm mobile database engine used by a couple of billion people worldwide, embedded in their mobile apps. I mainly worked on their Xamarin SDK in C# but had to use C++ in the glue layer to the engine.
  • Using the Cocos2D-X game engine, for mobile games (actually for my mobile messaging app which has a game-like interface).
  • Working on a 3D CAD program used to design minesites, including their roads, open-pits, tunnels and explosive blast patterns.

C++ is still a great language when you need to mix both high-level abstractions and compile down for really low-level performance.

Once of the cooler things happening is compiling C++ to JavaScript and WebAssembly, to deliver high performance graphical web apps like the Figma vector editor.

Even if they won't use C++ as a primary language, it's still important to know if you want to interface to some libraries.

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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