Hooray for bumping a 7 month old topic.
I've spent the past month or so reading through K&R's "The C Programming Language". I was actually managing pretty well until I got to the chapter on pointers. Once I got to a section that mixed pointers and arrays, my progress through the book ground to a halt and I was spending so much time debugging my programs that I decided to ragequit for the time being. After a little research, it seems C is really meant as a low-level language, and was even being compared to assembly. Considering that, I'm impressed I got as far as I did given my virtually nonexistent knowledge on concepts such as memory management.
It's clear that, at least for the time being, I want to be learning a high-level language, preferably dynamically typed and object oriented, something I can focus more on creating practical programs and less on debugging. Python seems like the perfect candidate, so I'll be focusing on that for the next month.
Joined: 10/6/2011
Posts: 1697
Location: RU · ID · AM
Yep, Python (as well as Ruby) is a good choice, especially considering the fact that you can use things like PyQt or PyGTK to create cross-platform GUI applications with ease. The same words can be said about web applications — there is Django for them. But I’d recommend you not to give up with pure C as well — such kind of knowledge may certainly become useful for you someday. For example, if you have to deal with microcontrollers, you’ll be able to write your firmware in C language.
Speaking of choice of the coding language, I can also recommend you trying Vala. It’s similar to C#, but it gets compiled into native machine code through source-to-source compiling into pure C.
S3&A [Amy amy%] improvement (with Evil_3D & kaan55) — currently in SPZ2
my TAS channel · If I ever come into your dream, I’ll be riding an eggship :)
You have a Linux (i386 or amd64) VM with Valgrind installed, right?
Valgrind is extremely powerful (if very slow) tool for debugging memory problems in C (and C++) code.
One of the major hurdles to learn and program in C (and to a large extent C++) is that you don't only need to know how to program in general and how to program in C in particular, but in addition you need to follow strict programming conventions in order to avoid the most typical and easy-to-do mistakes (such as leaking memory, using freed memory, accessing arrays out of boundaries, accessing memory through pointers that are pointing to completely wrong locations, using uninitialized variables...) These conventions are in no way enforced or checked by the programming language or compiler itself.
In most of the so-called higher-level languages it's either impossible to make such mistakes (eg. leak memory or use freed memory) or the runtime environment will always tell you exactly what went wrong (eg. accessing an array out of boundaries) thus not requiring any programming conventions that exist solely for the purpose of avoiding those mistakes.
C++ offers many tools that make it much easier to write safe code without having to follow so many programming conventions, but it isn't as easy as with other languages.
Joined: 3/18/2006
Posts: 971
Location: Great Britain
How is Python going?
I just picked it up a few days ago.
Like you, I was working my way through K&R until I realised I know next to nothing about programming, and perhaps C wasn't a good place to start.
To the programmers here, is there any point for me to learn C?
I'm learning programming only as a hobby, and I aim to only make windows applications. My only experience with programming is writing simple ASM programs, which I needed in order to understand FFVII's RNG functions (disasm).
Unless you plan to program for limited systems (eg embedded systems) or specific operating systems kernels, there is no point in learning C. In fact, it would only HURT you to learn C.
I'd say don't bother if that's the sort of programming you want to do. C is really only designed for situations where you're getting next to no help from the platform, either because it's very low-end and doesn't have an OS (e.g. most old consoles), or because you're trying to do something very high-performance beyond what a typical programming language can provide, or because you're actually writing the platform yourself (e.g. operating system development) and don't have another platform below that to help you out.
If you badly need to be able to control everything your program does, C is a good choice. But if you're working on a mature platform already (e.g. Windows development), you'll be better off with a language that doesn't force you to do everything yourself.
(Incidentally, if you want to get into Windows development in particular, you probably want to learn C#, which doesn't have much in common with C apart from the name. Too often, though, it seems that developing for Windows in particular isn't actually what you wanted, and you just want a program that anyone can run. In such cases, going for a language that isn't tied to a platform is more worthwhile.)
That depends. C++ is a much better choice than C, where it is possible to use since it allows you full control while remaining a high-end language rivalling Java, C#, etc.
Well, C++ is a pretty good all-around choice anyway since it doesn't restrict you to either high or low-level, is portable, etc.
Yes, for Windows development, C# is a pretty good choice. C++ also works, but is a little trickier (tested with Qt for GUI). Then there's also the Win8 Metro, which works with both C# and C++, though I am inclined to think that maybe C# is a little better in that department as of yet (particularly due to missing await keyword in C++).
That is, if you don't think you need to EVER make the program run well on anything except Windows.
Oh, and regarding using C++... Stay away from Win32 API as much as possible (especially for GUI tasks), as it is just bad.
And regarding WIn8 Metro, my advice is: Stay FAR away.
Actually, I'd call C++ a pretty bad all-around choice, for much the same reasons ;)
The problem is that you still have to take care of everything yourself, although now you're typically subcontracting the details to various libraries rather than doing it directly; and because C++ gives you so many options, it means that you have to learn all the options to have much of a chance of following someone else's code. I learned C++ back before, say, smart pointers were invented (or at least, had found their way to the textbooks and compilers I used), meaning that I have trouble following anyone else's code that uses them, and they'd likely have similar problems following my old code.
In general, I prefer languages that are good at one thing, and appropriate for that sort of problem. As such, I feel C is a better language; it's good at something that doesn't come up very often, but it's usually clearly the right language when it does. Languages that try to be good at everything too often end up doing nothing well…
Actually, I'd call C++ a pretty bad all-around choice, for much the same reasons ;)
The problem is that you still have to take care of everything yourself, although now you're typically subcontracting the details to various libraries rather than doing it directly; and because C++ gives you so many options, it means that you have to learn all the options to have much of a chance of following someone else's code. I learned C++ back before, say, smart pointers were invented (or at least, had found their way to the textbooks and compilers I used), meaning that I have trouble following anyone else's code that uses them, and they'd likely have similar problems following my old code.
I wouldn't call it bad. It's true that C++ has a higher learning curve, which is one of its disadvantages, but when you get the ball rolling, it becomes easier, so to speak.
When you learn how to put everything together, it becomes as easy as, say, C#. Don't forget that C++ is master of generic, too, so it has advantages no other language has. It's difficult, though, sure. So long as one understands that, I think it's fine.
In general, I prefer languages that are good at one thing, and appropriate for that sort of problem. As such, I feel C is a better language; it's good at something that doesn't come up very often, but it's usually clearly the right language when it does. Languages that try to be good at everything too often end up doing nothing well…
I don't really like languages that are good at one thing, because it means learning so many languages. It means having to use many different environments and compilers, etc. Of course, the reverse is true as you say. Specialized languages tend to be better at what they do.
Anyway, I don't feel like C is a good language. Oftentimes, C++ can do what C does - and better. There are only a few things C can do which C++ cannot, and I think the only one I can think of right now is the initializer syntax from C99. Then there's variable length arrays which has been voted into C++14. But then again, C++ can always use std::vector to get around that.
Even for simple tasks, it should be easy to see that C++'s many advantages makes even simple tasks easier, which is why I definitely would recommend it over C. C is really meant to be a minimalistic language for those exotic embedded systems.
Joined: 3/2/2010
Posts: 2178
Location: A little to the left of nowhere (Sweden)
Ilari wrote:
Oh, and regarding using C++... Stay away from Win32 API as much as possible (especially for GUI tasks), as it is just bad.
When coding for Windows only, please explain this, because as far as I know all CRT functions on one level or another maps to the Win32 API. Which means, that you will still end up using it, it just won't be as apparent from the code.
=====
Regarding C/C++ vs languages like C# / Java, I found that many who developed with C# / Java and then look into learning C/C++ have a higher difficulty remembering to use free/delete (correctly, or at all), and sometimes also have difficulties understanding proper indexing of arrays or other data-containers. It of course depends on what kind of programs you are interested in learning how to develop.
What I dislike most with languages like C# and Java though is that they compile into byte-code instead of actual CPU instructions requiring an extra interpreter / re-compiler layer to exist between the machine and the program in order for it to work, making it slower than it has to be. This is a little less of a problem with C#, but still a problem as it wastes CPU needlessly. While CPU power today isn't as limited as it was before, it's nonetheless slightly limiting the possibilities of your program. But this also depends on what you want to develop after learning the language, because today you will require some really advanced or computation heavy programs to really notice a difference.
When coding for Windows only, please explain this, because as far as I know all CRT functions on one level or another maps to the Win32 API. Which means, that you will still end up using it, it just won't be as apparent from the code.
Win32 API is:
- More difficult to use leading to more bugs
- Leads to more security issues being so low-level (eg buffer overflows)
- Inflexible (eg, can't take stateful lambdas as callback functions) which means that the code will be more obscure and uglier
- Difficult to use right, leading to more bugs and longer development time
- Requires manual memory management, requiring you either to fix memory leaks or write wrappers to use the RAII principle
What I dislike most with languages like C# and Java though is that they compile into byte-code instead of actual CPU instructions requiring an extra interpreter / re-compiler layer to exist between the machine and the program in order for it to work, making it slower than it has to be. This is a little less of a problem with C#, but still a problem as it wastes CPU needlessly. While CPU power today isn't as limited as it was before, it's nonetheless slightly limiting the possibilities of your program. But this also depends on what you want to develop after learning the language, because today you will require some really advanced or computation heavy programs to really notice a difference.
Though they will never be as fast as carefully optimized hand code, they are still pretty faster. Dynamic compilation on-the-fly compiles and optimizes the code in the background leads to efficient execution. I would be more worried about handling my resources as you never know when they feel like it's time to garbage collect it. This leads to you not knowing when locks on files are released and possibly also worry about that your program will freeze because the garbage collector must run. It's also an issue that it typically uses too much memory, never releasing memory when it's freed and also keeps the freed memory as a memory pool instead of releasing it to the OS.
Oh, and regarding using C++... Stay away from Win32 API as much as possible (especially for GUI tasks), as it is just bad.
When coding for Windows only, please explain this, because as far as I know all CRT functions on one level or another maps to the Win32 API. Which means, that you will still end up using it, it just won't be as apparent from the code.
Unlike Linux, Windows' actual kernel-level syscalls are a long way away from the actual APIs the programmer uses; they're very thick wrappers, rather than thin wrappers. You're getting substantially different functionality if you access the Windows kernel via .NET than if you access it via Win32 (USER/GDI/SYSTEM), as a result.
Regarding C/C++ vs languages like C# / Java, I found that many who developed with C# / Java and then look into learning C/C++ have a higher difficulty remembering to use free/delete (correctly, or at all), and sometimes also have difficulties understanding proper indexing of arrays or other data-containers. It of course depends on what kind of programs you are interested in learning how to develop.
This is because almost every language in existence does the free/delete at the appropriate time automatically for you; this is a solved problem on all but very resource-constrained systems. (Of course, the very resource-constrained systems are exactly the sort of systems on which C is designed to do well. Likewise, C++ is mostly used for games development, which is effectively resource-constrained because most games try to push the hardware to its limits, and thus don't have much to spare.)
What I dislike most with languages like C# and Java though is that they compile into byte-code instead of actual CPU instructions requiring an extra interpreter / re-compiler layer to exist between the machine and the program in order for it to work, making it slower than it has to be. This is a little less of a problem with C#, but still a problem as it wastes CPU needlessly. While CPU power today isn't as limited as it was before, it's nonetheless slightly limiting the possibilities of your program. But this also depends on what you want to develop after learning the language, because today you will require some really advanced or computation heavy programs to really notice a difference.
The penalty from going via bytecode is IIRC something like 1.5× to 2×, which is pretty small compared with the other overheads you get from high-level languages. Java tends to be pretty slow and bloated in practice, but that isn't because it uses bytecode (it's just as slow and bloated if you natively compile it with gcj), it's because Java's libraries have a huge number of levels of abstraction. C# and C++ are likewise noticeably slower than C if you use their standard libraries to their full potential, rather than trying to avoid them as much as possible; convenience tends to come with a performance penalty.
(You'll find that the commercial games which are typically written in C++ often ignore large swathes of the language in order to try to get as much performance as possible. It'd be pretty rare to use a reference-counted pointer, for instance, even though such pointers are common in C++ programming more generally.)
The problem is that you still have to take care of everything yourself, although now you're typically subcontracting the details to various libraries rather than doing it directly; and because C++ gives you so many options, it means that you have to learn all the options to have much of a chance of following someone else's code. I learned C++ back before, say, smart pointers were invented (or at least, had found their way to the textbooks and compilers I used), meaning that I have trouble following anyone else's code that uses them, and they'd likely have similar problems following my old code.
In general, I prefer languages that are good at one thing, and appropriate for that sort of problem. As such, I feel C is a better language; it's good at something that doesn't come up very often, but it's usually clearly the right language when it does. Languages that try to be good at everything too often end up doing nothing well…
ais523 wrote:
C# and C++ are likewise noticeably slower than C if you use their standard libraries to their full potential, rather than trying to avoid them as much as possible; convenience tends to come with a performance penalty.
This is very typical anti-C++ FUD spouted by C programmers, and it's completely false, and I would pay zero attention to it.
I especially find that last part quite ironic, given that the typical generic data containers written in C that I have seen are measurably less efficient than the equivalent data container in the standard C++ library (usually because the generic C implementation performs more memory allocations, which are a big bottleneck. The C implementation also often consumes more memory.)
In most cases the claims are made without any kind of actual measurement results, based solely on assumptions. In a few cases some claims might be based on measurements, but it often turns out that the wrong C++ container was being used for the job, or it was used in a suboptimal manner (possibly on purpose.)
I have programmed in C++ for over 15 years, almost 10 years professionally, and I use the standard library containers and other tools all the time. They make programming several orders of magnitude easier and safer, and I can assure you that they are no less efficient than any equivalent in C. On the contrary, in some cases they can be more efficient.
Even if the C++ containers were less efficient, they would still be very useful because you can write one-liners in C++ that require dozens if not hundreds of lines in C. That alone would be reason enough. Luckily, they are not less efficient.
(There is one exception: C++ streams are measurably slower than the C I/O functions. This is a fact. If maximal file handling speed is required in a program, one has to resort to the C-style I/O functions. They are part of the C++ standard as well, so they are available if needed. However, while this exception is a real case where the C standard library beats the C++ one, it tends to be the only case.)
The general takeaway here is that the more you design your system to be flexible and readily-extensible (e.g. by using higher-level languages, by using templates or other type-agnostic systems; by using an automatic garbage collector; etc.), the more you pay in performance.
Oldschool programmers made every single bit count, because that's what they had to do to get the program to fit and to get it to run at a reasonable speed. However, that also meant that if they ever had to change anything, it was a colossal amount of work! These days most people tend to want to make their code more flexible and more easily-modified, but this comes at the cost of speed and efficiency.
As an example, I was talking in this forum a month or so ago about implementing save/load functionality in the game I'm working on. I've implemented a working system, now, but it's rather inefficient -- it takes 4-5 seconds to save a rather simple game state, and the savefile is 25 megabytes! This is pretty terrible. However, the save/load system is very easy to use and can be trivially extended to handle new situations.
I could write a much faster save/load system, but it would come at the following costs:
1) It would take me longer to implement.
2) It would have to enforce constraints on what exactly could be saved (meaning, you'd have to modify it if you wanted to support different behaviors).
3) The code would be harder to understand (and thus, harder to modify).
Dick-waving about which language does X better is really just arguing about how much you care about speed vs. the above three items.
For what it's worth, my opinion is that most code does not need to be fast/efficient these days, because most code doesn't actually run all that often. So you should write everything in the most pleasant language you have, find the points that actually require efficiency, and optimize those bits by whatever means seem reasonable -- potentially including rewriting them in a different language.
Pyrel - an open-source rewrite of the Angband roguelike game in Python.
The general takeaway here is that the more you design your system to be flexible and readily-extensible (e.g. by using higher-level languages, by using templates or other type-agnostic systems; by using an automatic garbage collector; etc.), the more you pay in performance.
It's a mistake to put all "higher-level" features into the same "reduces performance" category. You should get your facts straight before carelessly listing things that don't belong.
One of the main design principles behind the C++ template feature is that they don't make the program more inefficient than the explicit alternative. Basically, templates are evaluated at compile time, rather than at runtime, which means that the compiler has all it needs to make the program as efficient as if templates hadn't been used (and instead the code had been written explicitly for a certain type.)
On the contrary, templates sometimes produce faster code than an equivalent generic implementation in C. You just have to compare std::sort() to qsort(). (The reason that qsort() is slower than std::sort() is because with the former the compiler cannot perform type-specific optimizations, and there are additional indirections that std::sort() doesn't need.)
OK, my humble 2 cents.
For the tl;dr:
My overall advice is, if you want to avoid the learning curve of C++, or you need to write code for an architecture where no optimized C++ compiler exists, or you want to avoid the long compile times and incomprehensible C++ error messages, you should code in plain C. For all other situations you should use C++.
For those who are more technically inclined:
The claim that C++'s generic containers put some performance overhead compared to C is false for most of them. Streams are very slow and I never use them, and the boost ref counting pointers which are now part of the standard are noticeably slower than C pointers and even slower than some garbage collected languages, and if you do some ugly casts, your code might need RTTI, which reduces performance. Nevertheless, any experienced C++ programmer will know how to optimize that stuff when he needs to and I think C++ code is easier to optimize than C code.
That said, though, C++ is so poorly designed that it's embarassing. I love C++, but most of the time I find myself using only object oriented C with a larger standard library, and I constantly have to remind other people not to do what seems to be natural. I honestly think it's impossible for a common programmer to really master C++, there must be at most 10 people who've mastered it, probably all in the standard committee. There are a lot of silly details like the difference between "typename" and "class" in template declarations, difference between static functions and functions in an anonymous namespace, using ios::sync_with_stdio() to speed up streams, make_shared() being faster than shared_ptr constructors, etc. These are the ones I can remember, people more experienced than me can probably list much more.
Besides, there are some things which make no sense at all and do a lot of harm:
* The cascade of constructor calls that may happen when you don't declare them explicit is so ridiculous that one wonders if there's a rational explanation for that stuff (there is, they realized it was a mistake after the first versions, but had to be backwards compatible).
* Exceptions can behave quite unexpectedly when you link libraries compiled with different compilers. Many C++ experts recommend a much more strict approach to exceptions at module boundaries because of this behavior. It can be such a nightmare that a large company like Google simply chooses to ban C++ exceptions altogether.
* The throw() signature for functions is so stupid that nobody uses it.
* The keyword "register" and, before C++11, "auto" have the exact same meaning as whitespace. However, they are still there to make you confused.
* Names of functions in the STL like fill() and distance() clash with pretty much anything. That means that you have to resort to C-style name conventions or just pepper the code with std:: or "using std::foo;" statements, which is extremely annoying.
* Ultimately, even the designers of the language found out that writing namespaces inside deeply nested template functions is annoying, so they made ADL, which has an algorithm so complicated that I've met only one person who understands it (Bjarne Stroustrup, whom I met at one of his talks in Russia). Seriously, not even compiler writers understand it, some time ago I saw code that worked in some compilers and not on others, because the compiler got ADL wrong.
* While C, like most languages, has context-free grammar, C++ has undecidable grammar. That means that the gcc parser needs hundreds of thousands of lines to parse C++, that C++ code has excrutiatingly long compile times, and that there'll never be neat IDE features like those of Eclipse for Java.
Anyway, this should not give the impression that I think C++ is a bad language. It has its flaws, like any language, I just rant a little bit because the committee has not learned from its previous mistakes and in C++11 they continue to make the language more needlessly complicated while people still need "idioms" to do basic stuff and fundamental things like concurrent programming are still not implemented.
My overall advice is, if you want to avoid the learning curve of C++, or you need to write code for an architecture where no optimized C++ compiler exists
Yes, because that's the major issue for a beginner programmer.
or you want to avoid the long compile times
I stand corrected. That's most certainly the major issue. Especially for the 100-line programs that a beginner programmer is going to make.
Streams are very slow and I never use them, and the boost ref counting pointers which are now part of the standard are noticeably slower than C pointers
Your term "C pointers" is a misnomer. They are commonly called "raw pointers". And there's nothing that forces you to use smart pointers in C++. You make it sound like there is. (This is highly deceptive for someone who doesn't know the languages yet. They get the impression that in C++ you are forced to use smart pointers.)
if you do some ugly casts, your code might need RTTI, which reduces performance.
Have you done actual measurements that RTTI reduces performance, or is it solely based on assumptions?
(I actually have. Eg. the speed difference between calling a virtual function and a normal function is practically immeasurable. The few clock cycles more that it requires gets swamped by everything else that's done in order to call a function.)
I love C++, but most of the time I find myself using only object oriented C with a larger standard library
Then you are needlessly restricting yourself.
There are a lot of silly details like the difference between "typename" and "class" in template declarations, difference between static functions and functions in an anonymous namespace
What differences are those?
* The cascade of constructor calls that may happen when you don't declare them explicit is so ridiculous that one wonders if there's a rational explanation for that stuff
Make a guess how many times that has been a problem for me during the 15+ years I have actively programmed in C++.
* Exceptions can behave quite unexpectedly when you link libraries compiled with different compilers.
Guess how many times.
* The keyword "register" and, before C++11, "auto" have the exact same meaning as whitespace. However, they are still there to make you confused.
You can thank C for that. However, who exactly finds that confusing?
* Names of functions in the STL like fill() and distance() clash with pretty much anything.
Which is why namespaces exist.
That means that you have to resort to C-style name conventions or just pepper the code with std:: or "using std::foo;" statements, which is extremely annoying.
No, what's stupid is the irrational hatred of namespace prefixes. It makes no sense.
Namespace prefixes not only disambiguate the code, they also make it easier to read. And yes, I can present an argument for that. It's not a spurious claim.
* Ultimately, even the designers of the language found out that writing namespaces inside deeply nested template functions is annoying, so they made ADL, which has an algorithm so complicated that I've met only one person who understands it (Bjarne Stroustrup, whom I met at one of his talks in Russia). Seriously, not even compiler writers understand it, some time ago I saw code that worked in some compilers and not on others, because the compiler got ADL wrong.
I think you are now pulling things from your behind. Try to guess exactly how many times any of that has been a problem during the 15+ years I have been programming in C++.
* While C, like most languages, has context-free grammar, C++ has undecidable grammar. That means that the gcc parser needs hundreds of thousands of lines to parse C++, that C++ code has excrutiatingly long compile times, and that there'll never be neat IDE features like those of Eclipse for Java.
Guess how many times.
and in C++11 they continue to make the language more needlessly complicated
Joined: 10/6/2011
Posts: 1697
Location: RU · ID · AM
IMHO, choice of the coding language for learning should depend on what tasks you are going to solve. Sometimes scripting languages are even better than compiling ones — an example case is if you are going to work in a company where you’ll have to implement automation of various processes… Such tasks may involve knowledge of bash, Python, Perl & so on. Web programming would require knowledge of languages for which there are good MVC frameworks present. PHP, Python, Ruby are good candidates. Finally, if you are going to write GUI applications, you’ll probably have to deal with C, C++ (as there are such frameworks as GTK, Qt and others). So, the task and the tools should help to make the choice.
Tool assisted speedrunners approve this frameworkAs well as this XMPP server
S3&A [Amy amy%] improvement (with Evil_3D & kaan55) — currently in SPZ2
my TAS channel · If I ever come into your dream, I’ll be riding an eggship :)
I think you are now pulling things from your behind.
Guess what you are full of?
I was gonna reply until I saw those. I don't think it's possible to have a constructive discussion with someone who starts saying stuff like this to people who disagreed so little about C++, if you think C++ is a masterpiece of design, fine, but since we're at this point now, you do seem the textbook example of an annoying language evangelist.
My overall advice is, if you want to avoid the learning curve of C++, or you need to write code for an architecture where no optimized C++ compiler exists, or you want to avoid the long compile times and incomprehensible C++ error messages, you should code in plain C. For all other situations you should use C++.
I disagree. That's just silly. You are advocating a language meant for embedded or otherwise resource constrained systems over modern languages that are meant for rich desktops systems just because of longer compile times and horrible error messages (yes, C++ can have horrible error messages).
C++ also have techniques for reducing compile time. Not something a beginner might want to dive into to solve it right away, of course.
I think it is much better to simply use another high-level language such as C# instead. If you are going C, you will trade compile times and error messages for extreme complexity. That's just silly.
The claim that C++'s generic containers put some performance overhead compared to C is false for most of them.
I don't believe you. Most of these containers have been optimized for performance and is more stable, more secure, have less bugs and are probably faster than equivalent C, because most often, they are hand-rolled, whereas the C++ containers are part of library and hence done by compiler vendors. Yes, sometimes these can be slow or buggy due to compiler vendors writing poor code. It happens. But the same is true for C.
...and the boost ref counting pointers which are now part of the standard are noticeably slower than C pointers and even slower than some garbage collected languages...
Ummm yes, of course they are. You are adding overhead logic wrapped around them, so how they not be slower? But the point is: how much slower are they? If you use them right, it turns out, not so much. An insignificant amount, I'd say. The problems lie in std::weak_ptr and often recursive destruction of the resource they are holding. std::weak_ptr is terribly slow (but often that does not matter) and recursive destruction can cause stack overflow (has happened to me).
But abstraction is always slower. But that's fine, so long as we really don't need that extra speed, and often, we don't.
Smart pointers can be slower than garbage collection, true, but then again, they offer advantages garbage collection can not: deterministic destruction. No sitting on memory or resource longer than necessary.
...and if you do some ugly casts, your code might need RTTI, which reduces performance.
Sure, but such casts are often frowned upon, and they are not so common. If they are, you really should think about your design a little bit more.
That said, though, C++ is so poorly designed that it's embarassing. I love C++, but most of the time I find myself using only object oriented C with a larger standard library, and I constantly have to remind other people not to do what seems to be natural. I honestly think it's impossible for a common programmer to really master C++, there must be at most 10 people who've mastered it, probably all in the standard committee.
Do point out some of these points. What is natural which is bad?
It's true that C++ is very difficult to master, though. This is unfortunate truth but a tradeoff due to the flexibility.
There are a lot of silly details like the difference between "typename" and "class" in template declarations, difference between static functions and functions in an anonymous namespace, using ios::sync_with_stdio() to speed up streams,
Yes, a lot of is to ensure code isn't broken. I think you will see it in "any" language. That's an unfortunate truth that we're just going to have to accept. But that doesn't make it poorly designed.
make_shared() being faster than shared_ptr constructors, etc.
That's because it's not possible to do some optimizations in the shared_ptr's constructor as make_shared can do because it has a bigger picture. That's hardly poor design.
You could argue, then, that we should remove the ability to call the constructor directly and only use make_shared. Sure, that would take care of that nitpick, but it would also break older code and lose flexibility.
* The cascade of constructor calls that may happen when you don't declare them explicit is so ridiculous that one wonders if there's a rational explanation for that stuff (there is, they realized it was a mistake after the first versions, but had to be backwards compatible).
Flexibility and power. It's not silly and it's not ridiculous. It's natural, even. If we have a function that takes a complex number and we supply it with a real number, would you not expect it to work? It's natural in such a way.
Sure, it's also dangerous in some ways, but C++ is a language that does not restrict dangerous features simply because they are dangerous.
* The keyword "register" and, before C++11, "auto" have the exact same meaning as whitespace. However, they are still there to make you confused.
"register" does not have the same meaning as "auto" (even before C++11). But regardless, they exist in C too, so what are you complaining about?
* Names of functions in the STL like fill() and distance() clash with pretty much anything. That means that you have to resort to C-style name conventions or just pepper the code with std:: or "using std::foo;" statements, which is extremely annoying.
Personal opinion. In C, you'd always type of name_of_library_function. How is this different from C++'s name_of_library::function? There is a reason namespaces exist, and if you ignore them, then that's your problem, not the language's.
* Ultimately, even the designers of the language found out that writing namespaces inside deeply nested template functions is annoying, so they made ADL, which has an algorithm so complicated that I've met only one person who understands it (Bjarne Stroustrup, whom I met at one of his talks in Russia). Seriously, not even compiler writers understand it, some time ago I saw code that worked in some compilers and not on others, because the compiler got ADL wrong.
It's necessary due to how operators are created in the language. I do think it could have done better, though, so we could avoid this feature since it can do much Evil™.
I don't think it exists because of the reason you specify.
...and that there'll never be neat IDE features like those of Eclipse for Java.
That's silly. You are right in that it is complex to parse, but that doesn't mean tools will pop up eventually. They are already popping up, and I don't know which things you want exactly.
Anyway, this should not give the impression that I think C++ is a bad language. It has its flaws, like any language, I just rant a little bit because the committee has not learned from its previous mistakes and in C++11 they continue to make the language more needlessly complicated while people still need "idioms" to do basic stuff and fundamental things like concurrent programming are still not implemented.
Oh, I think they've learned something alright. The problem was that they took 13-ish years from the previous full standard (not the minor C++03 standard) to make the next one. Now they're reducing that to 3-4 years and pumping out library updates asynchronously.
But you know, a language is extremely complicated, especially as it gets older. You complain they make mistakes, but can you do better? Can other languages really do better? I'm not so sure.
Idioms exist simply because they simplify things. They exist in all languages. It is not fair to say you need idioms to solve even trivial things. Idioms are what makes and breaks a language. You should learn them.
Do point out some of these points. What is natural which is bad?
It's true that C++ is very difficult to master, though. This is unfortunate truth but a tradeoff due to the flexibility.
Example of things that are natural and bad: declaring a single argument constructor without "explicit", using a throw signature in a function, throwing an exception out of a destructor (which is not forbidden by the language and causes hell if you do it), putting stuff in an initializer list that's not initialized in the order you put them, using the keyword "register" thinking it does something, etc.
And of course, you can justify any feature using the flexibility card, but the things I brought about only give you flexibility to shoot yourself in the face. Granted, they can be useful for something, just like a stopped clock gets the hour right twice a day.
EEssentia wrote:
"register" does not have the same meaning as "auto" (even before C++11). But regardless, they exist in C too, so what are you complaining about?
Before C++11, they do have the same meaning, which is no meaning. After C++11, auto as a modifier continues to do nothing, just like register. They do nothing at all, the compiler just eats them. In C "register" retains its original meaning (afaik, for some platforms it might mean nothing too).
EEssentia wrote:
Personal opinion. In C, you'd always type of name_of_library_function. How is this different from C++'s name_of_library::function? There is a reason namespaces exist, and if you ignore them, then that's your problem, not the language's.
There's little difference, that's the whole point, namespaces only cause confusion. And by the way, I'm not the only one to criticize namespaces, one of the people who worked in C++ criticize them as well: http://www.informit.com/guides/content.aspx?g=cplusplus&seqNum=286EEssentia wrote:
But you know, a language is extremely complicated, especially as it gets older. You complain they make mistakes, but can you do better? Can other languages really do better? I'm not so sure.
Idioms exist simply because they simplify things. They exist in all languages. It is not fair to say you need idioms to solve even trivial things. Idioms are what makes and breaks a language. You should learn them.
Why do you think I should be able to do better? Can't I say a meal is bad without knowing how to make a better one? What's the reasoning behind that?
Anyway, since you asked, Scala gets my trophy for the best designed language (of course, Scala depends on a lot of Java crap and at the current state is blown out of the water in almost everything by other languages, but its design has been extremely good).
Of course any language has complications and idioms, that has little to favor C++, though, the number of idioms and complications in C++ is disproportionally high.
I was gonna reply until I saw those. I don't think it's possible to have a constructive discussion with someone who starts saying stuff like this to people who disagreed so little about C++, if you think C++ is a masterpiece of design, fine, but since we're at this point now, you do seem the textbook example of an annoying language evangelist.
No, I don't consider C++ to be "a masterpiece of design." What irks me is when people start inventing flaws that it doesn't have (eg. templates being slower than explicit code), or exaggerate problems that are completely inconsequential in 99.99% of cases (such as compiling times being longer in certain situations.)
If you had stated actual problems C++ has compared to other languages, accurately and without exaggeration, then I wouldn't have had any complaint.
For example, there are some things that one just has to know and have experience about if one wants to achieve and surpass the speed of other, higher-level languages. For instance, dynamically allocating a million individual objects is much slower in C++ than it is eg. in C# or Java. That's because C++ is stuck with the standard clib memory allocator, which is horribly slow. (There are ways to make allocation much faster in C++, but they require specialized allocators.) This means that if one wants to write efficient code, one needs to avoid doing excessive amounts of individual memory allocations as much as possible. (In other words, prefer allocating entire arrays of objects as single allocations rather than allocating each individual object separately.)
C++ streams tend to be significantly slower than C I/O functions, which means that if maximum I/O speed is required, one has to resort to using the latter. (The advantage of C++ streams is that they are more type safe and in some situations much easier to use and more flexible.) Of course this doesn't mean that a C++ program necessarily is slower in terms of I/O than a C program; it just means that you need to be aware of this when programming, and you need to learn the C functions. This can be an extra burden when learning the language.
Of course compared to languages like C# and Java, memory handling requires more experience and care. Experienced C++ programmers have developed a natural instinct to avoid such problems in the vast majority of code, but this is something that requires a lot of learning, and therefore beginners will struggle with it for a long time. In higher-level languages one seldom needs to worry at all about memory handling issues. (On the other hand, C++-style memory handling also has its advantages in some situations, such as deterministic destruction of objects and handling objects by value, which brings up the possibility of automatically managing things other than memory.)