C++ and C are completely different beasts. C is an elegant clean small language with few distracting elements, making it very suitable for a teaching language. C++ is a grotesquerie more suitable for a carnival horror show than something you want to introduce to new programmers.
Unfortunately at some point, teaching OOP became all the rage in schools, and so C++ is chosen instead. That's a mistake, Java or C# should be used for teaching OOP, C should be used to teach data structures and at least some algorithms. Without hands on memory allocation, you're not really getting a full understanding of how data structures work.
"C++ is a grotesquerie more suitable for a carnival horror show than something you want to introduce to new programmers."
In my experience TAing an undergrad course that used C++, almost all of the things that left students scratching their heads were things that are present in C. No garbage collector, no built-in way to determine array sizes at runtime, no way to determine if a pointer has already been deallocated, no requirement that non-void functions actually return a value on all control paths, etc. The worst thing C++ does is to amplify these problems (particularly that last one -- yes, I know, use -Wall, but someone who is just starting to use a language would not know that, and having to teach compiler flags is an even worse distraction from the subject matter of the course).
Really the problem is not language size at all. Python is a big language too, but it does not have the above problems. Common Lisp is just as big as C++ (in terms of the number of pages in the standard), yet these are not problems Lispers have. Scheme is a small language, like C, yet the elegance and expressive power of Scheme is on a completely different level from C.
The problem is that the few abstractions C presents are hard to deal with, especially for beginners, and the abstractions that C could present are sorely missed. Even the abstractions C presents are unreliable, with loads of undefined behavior and plenty of ways to break the abstractions.
Really, the fact that real-world C programmers have to pick a subset of the language and enforce various style standards and coding conventions speaks volumes about the suitability of C for beginners. If we were going to require students to use a specific subset of C, why not just write a compiler for that subset and use that to teach? The answer is pretty clear: if we were going to write a compiler for a new language that was suitable for teaching students, we would write something better. Why bother when we already have better languages to choose from? Save C for the OS course, and only as long as it remains relevant there.
I completely agree. Its kind of sad to see student get stuck on simple tasks on problems that would never show up in a higher level language and end up just serving to distract them.
The undefined behaviour is particularly bad. Its hard to tell if a wrong result is coming from a wrong algorithm or from some undefined behaviour that is silently messing up your results and this only serves to confuse students. Its also a PITA to debuig segfaults - even just getting a stack trace means that you need to use a separate debugger tool.
Another thing you didn't mention about the garbage collection is that it makes it much harder to do string handling. For example, the simple task of reading a name from standard input has multiple solutions and but all the simple ones (scanf and gets) are potentially dangerous. And this is not counting the off-by one erros in allocation because of forgetting to account for the null terminator.
It was a course on data structures, not on the C++ standard library. Referencing counting would have been the wrong thing for the lesson on doubly linked lists -- which was basically the first lesson of the course. "Modern" C++ would not have helped at all for the student who had a function with a missing return statement and a confusing error log.
Frankly, almost none of the C++11 features are actually useful for teaching data structures, and those that are relevant would only confuse students. Basically, only auto and the three kinds of smart pointers are relevant to an introductory data structures course. At the end of the day those would only create as many problems as they solve. For example, unique_ptr means that there is only one "owner," right? Wrong, get() returns a raw pointer to the object, and you can make a new unique_ptr from that. Sure it is easy to avoid -- if you are an expert with lots of C++ experience, who follows coding guidelines and all that. The data structures students had little to no C++ experience and would almost certainly have done what I just described -- and that is just one of many ways they can and will screw up C++11 features.
At the end of the day, C++ is too complicated, too poorly defined, and has all the wrong abstractions for basic CS courses.
So you were basically teaching C? How does C++ come into this discussion at all?
How do you teach a basic data structure course in Python?
Pascal seems like a much better choice for data structures than C or C++. Or you can use Scala and teach functional data structures if you're adventurous ...
Could you name some of the subsets of C? I know of several in C++ (exceptions, templates, multiple inheritance, smart structures) but even after programming in C for twenty years, can I come up with any number of subsets of C (okay, maybe one---function pointers).
no requirement that non-void functions actually return a value on all control paths, etc. The worst thing C++ does is to amplify these problems (particularly that last one -- yes, I know, use -Wall, but someone who is just starting to use a language would not know that, and having to teach compiler flags is an even worse distraction from the subject matter of the course).
Use clang ?
root@iwfvm02086 ~/temp/c_test # cat test.c
#include <stdio.h>
int a_func(int a_bool)
{
if( a_bool )
{
printf("Passed variable was true\n");
}
else
{
printf("Passed variable was false\n");
return 0;
}
}
int main()
{
int num = a_func(0);
printf("In main : num = %d\n",num);
}
root@iwfvm02086 ~/temp/c_test # g++ test.c -o test
root@iwfvm02086 ~/temp/c_test # ./test
Passed variable was false
In main : num = 0
root@iwfvm02086 ~/temp/c_test # clang++ test.c -o test
clang: warning: treating 'c' input as 'c++' when in C++ mode, this behavior is deprecated
test.c:14:1: warning: control may reach end of non-void function [-Wreturn-type]
}
^
1 warning generated.
root@iwfvm02086 ~/temp/c_test # g++ --version
g++ (GCC) 4.4.6 20110731 (Red Hat 4.4.6-3)
Copyright (C) 2010 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
root@iwfvm02086 ~/temp/c_test # clang++ --version
clang version 2.8 (branches/release_28)
Target: x86_64-redhat-linux-gnu
Thread model: posix
Really, the fact that real-world C programmers have to pick a subset of the language and enforce various style standards and coding conventions speaks volumes about the suitability of C for beginners
I am confused; all languages used in real world need this. Can you elaborate which languages are used in real-world that does not require coding standards ?
No garbage collector, no built-in way to determine array sizes at runtime, no way to determine if a pointer has already been deallocated
These are also side-effects for having the advantages you have teaching C for a Computer Science and Engineering course. Once you understand the fetch-decode-execute model of how a computer essentially works, it is a simple step from there to C.
I agree that, higher level concepts like Algorithms, Neural Networks are better taught with a higher level language.
Pointers, raw arrays, manual memory management... So, really, you were teaching C. Now, I'm all for teaching beginners the basics, but don't pretend you were actually teaching C++ as it would be used in the real world.
> In my experience TAing an undergrad course that used C++, almost all of the things that left students scratching their heads were things that are present in C.
Then why are you teaching C++ like you are teaching C?
> C++ is a grotesquerie more suitable for a carnival horror show than something you want to introduce to new programmers.
I bought into this previously after hearing it constantly repeated, but don't anymore. Your point about OOP is fair, but I think there is a sane subset of C++ that is incredibly useful for teaching new programmers. One thing to be avoided is needless OOP hierarchies. User-defined types are an incredibly powerful abstraction, and makes certain programming tasks look and feel extremely natural. If you listen to Stroustrup talk about C++, this is what he tends to highlights about C++, not the advanced features. Those can come later.
C++ has plenty of warts, and I dislike certain parts of it as much as its detractors, but C++ is still an awesome language.
I think the same way. Nowadays I jump between JVM and .NET ecosystems.
For me C was just one year transition between Turbo Pascal and C++, back in the mid-90's. Only used it for university assigments and on my first job. Otherwise when the option is reduced to C vs C++, I always pick C++.
For me, C was too litle when comparing with what Turbo Pascal offered me. Luckly I discovered C++ shortly after learning C.
While I definitely think everyone should learn C in college, I don't think it should be a first language. I'm currently teaching it in high school, and the amount of pain that goes into something as simple as managing arrays makes it extremely intimidating for students.
I would recommend a language like Python, where simple data structures like lists and dictionaries can be created on a whim, freeing up students to tackle more fun problems.
Unfortunately at some point, teaching OOP became all the rage in schools, and so C++ is chosen instead. That's a mistake, Java or C# should be used for teaching OOP, C should be used to teach data structures and at least some algorithms. Without hands on memory allocation, you're not really getting a full understanding of how data structures work.