Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C: Good Habits re: Transitioning to C++

Tags:

I've been learning C at Varsity for just shy of 2months now, and next year we'll be moving on to C++.

Are there any habits I should get into with my C programming which will aid a transition to C++ in the future, or is it best to think of them completely separately ?

When you learnt C then C++, did the way you coded in C change in any way ?

like image 590
Ande Turner Avatar asked Sep 14 '09 10:09

Ande Turner


Video Answer


2 Answers

There are already a lot of good answers. Mine will be more "mindset oriented".

Data vs. Action!

  • In C, everything is done to think like "Apply this effect to this data".
  • In C++, this is more like "Data should behave".

While the "Data should behave" can be done in C (and it is done!), in C++, everything needed to implement this easily is already accessible : Encapsulation, constructors, overloading overriding, templates, etc..

I found this "Data should behave" idea a very good guiding principle when coding in C++.

C++ syntactic sugar is not optional

You'll find a lot of C++ features that could be done in C, and some people use it as an excuse to not learn them. This mindset is dangerous (this is the part "treat C++ as a new language, and not an extension" seen in some posts).

A side effect of avoiding writing C++ the C++ way is that while a C++ developer is supposed to understand C++ code, he/she is not supposed to understand your little personal framework mimicking C++ sugar with C-only features. In fact, he/she won't be interested by your framework. Truth to be said, he/she will only feel pity/contempt for you because you lost precious time producing that. Ultimately, he/she will hate you if he/she must use your framework instead of the C++ sugar.

Guiding principles like "I can do this the C way" will just make you miss the wagon. Better not to start learning C++ at all if you already have this kind of C-centric mode of thinking.

Your language of choice is never the best. YOU are supposed to become the best. If you write C++ code, then write it the C++ way.

C-compatible C++ code is a semantic error

Typedefing your structs to make them compilable by a C compiler is a bad joke. Using pointers instead of references is a slap to your future self. The extern "C" will only make your code weaker, not stronger. And using void * for genericity will only increase the number of fellow C++ coders who will gladly pay to have your head removed in a spectacularly painful way.

Don't ever bother to write C-compatible code unless you really really really have to.

You'll just weight yourself down with a time-consuming coding style for a feature you'll never use.

The compiler is a powerful friend/enemy

Working low level has strange effects on some developers. They believe a lot on their control of the compiled code. Delegating this control to higher-level constructs is difficult for them.

A good example of that is ditching the constructor/destructor pattern because "sometimes, constructors takes too much time... Better to do it my way...".

The C++ compiler is quite able to optimize apparently unoptimized code. In fact, the code produced by the compiler can be quite different from the one you believe you produced.

Don't try to be better/smarter than the compiler is because:

  1. You probably already lost the fight, as even old compilers will usually produce better code than you can dream to do today
  2. Even if you did win the fight today, it will automatically turn into a defeat tomorrow, as compilers will become better and better in the future, so your "optimized code" of today will become the program bottleneck and refactoring subject of the next years (not mentioning shameful memories for you).

So, trust your compiler.

Don't micromanage the production of your code. Do your own work, and let the compiler do its own.

Note that this point should not be used to justify production of slow/inefficient code. If premature optimization is the root of all evil, you must still use your knowledge of the language and the compiler to produce good and efficient code (see the next point).

Know the advantages/drowbacks/costs of each C++ construct

For example, the fact virtual methods adds one indirection to the function call means for some people that performance will decrease dramatically. Truth is, performance problems are often elsewhere.

Ignorance is no excuse.

Know the code produced for each C++ construct (i.e. inlining, references, constructor, destructor, exception, function overload, function override, template, virtual function, etc.). Know what will be optimized away, and what won't.

This way, not only you won't pay for what you don't need (this is a guiding principle of C++), but you will also profit from what costs you zero but brings you a lot.

Be humble

There are people doing research in C++ that were better at C++ the day of their birth than most of us will ever be. Even if we ignore Stroustrup, names like Meyers, Abrahams, Alexandrescu, Sutter, etc. regularly crop up alongside new ideas. Despite (or as a consequence of) its alien outlook, STL is revolutionary library. And a library like Boost, despite its "small size" when compared to some complete frameworks (like Java or .NET APIs), is a massive repository of excellent code offered to you to study.

Just because you find some new feature "strange" or "alien", don't underestimate it. Trying to understand it will PERHAPS bring you another tool at your disposal, and will ALWAYS increase your mastery of the language, and will ALWAYS make your brain work, which is a good thing in the dev business.

Most people I know who failed their "conversion to C++" just assumed this or this feature was useless because they did not bother to understand it.

RAII !!!!

If you don't know what it is, learn it.

Without RAII, your C++ code is just bugged code that avoided compilation error.

RAII is the single most important notion of C++.

Everything else is related.

like image 118
paercebal Avatar answered Sep 30 '22 07:09

paercebal


The best advice is probably to treat them as completely separate languages. Yes, most C code can be compiled by a C++ compiler, but it's generally not a good way to go.

C is very much a low-level hackery language. What you see is what you get. It has pointers and structs, so you use pointers and structs. It has very little type safety, so you ignore type safety as much as possible.

C++ on the other hand, allows a huge number of abstractions. Rather than pointers, you'll typically want to use iterators, which behave conceptually as pointers, but aren't (or might not be).

Instead of throwing away type information (for example having functions accept a void* so they'll work with any pointer type), you can use templates to retain type safety and still be able to reuse the same single function definition.

And you're given an excellent standard library which enables you to express complex algorithms in terms of simple predefined building blocks.

C++ is a multi-paradigm language. Some answers here have said that C++ is object-oriented, which is partially true. It does have support for object-oriented code, yes, but that's not what C++ is.

C++ also has support for generic programming, which is often preferable over OOP. It has some limited support for functional programming as well. And of course, it still has support for C-style procedural programming as well. The trick in C++ is to understand all of these, so you know which to use when. That is C++'s strength, the ability to switch between and mix all these paradigms. People who call C++ an OOP language miss the point just as much as people who call it an improved C. It allows you to write code in either of these styles, but neither of these are really worthwhile in themselves. C is a better C-like language, and there are plenty of better OOP languages. If you want to stick to one single paradigm, use a language designed for that.

like image 30
jalf Avatar answered Sep 30 '22 06:09

jalf