Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Learning C when you already know C++?

Tags:

I think I have an advanced knowledge of C++, and I'd like to learn C.

There are a lot of resources to help people going from C to C++, but I've not found anything useful to do the opposite of that.

Specifically:

  1. Are there widely used general purpose libraries every C programmer should know about (like boost for C++) ?
  2. What are the most important C idioms (like RAII for C++) ?
  3. Should I learn C99 and use it, or stick to C89 ?
  4. Any pitfalls/traps for a C++ developer ?
  5. Anything else useful to know ?
like image 940
KeatsPeeks Avatar asked Dec 16 '09 16:12

KeatsPeeks


People also ask

Should I learn C if I already know C++?

C++ is mostly backwards compatible with C. However it is very possible to write C code that will not compile as C++... usually by using a C++ keyword as a variable name or something. That depends on the software doing the interpreting.

Is it easy to go from C to C++?

Switching from C to C++ can be both easy, as there are many similarities between the two languages, and hard, as there are many differences that require forgetting what you know and habits that you may have developed from programming in C.

Is learning C worth it in 2022?

C is worth learning in 2022 because it is easy to grasp. It gives you basic knowledge about the inner workings of computer systems and the core concepts that drive programming.


1 Answers

There's a lot here already, so maybe this is just a minor addition but here's what I find to be the biggest differences.

Library:

  • I put this first, because this in my opinion this is the biggest difference in practice. The C standard library is very(!) sparse. It offers a bare minimum of services. For everything else you have to roll your own or find a library to use (and many people do). You have file I/O and some very basic string functions and math. For everything else you have to roll your own or find a library to use. I find I miss extended containers (especially maps) heavily when moving from C++ to C, but there are a lot of other ones.

Idioms:

  • Both languages have manual memory (resource) management, but C++ gives you some tools to hide the need. In C you will find yourself tracking resources by hand much more often, and you have to get used to that. Particular examples are arrays and strings (C++ vector and string save you a lot of work), smart pointers (you can't really do "smart pointers" as such in C. You can do reference counting, but you have to up and down the reference counts yourself, which is very error prone -- the reason smart pointers were added to C++ in the first place), and the lack of RAII generally which you will notice everywhere if you are used to the modern style of C++ programming.
    • You have to be explicit about construction and destruction. You can argue about the merits of flaws of this, but there's a lot more explicit code as a result.
  • Error handling. C++ exceptions can be tricky to get right so not everyone uses them, but if you do use them you will find you have to pay a lot of attention to how you do error notification. Needing to check for return values on all important calls (some would argue all calls) takes a lot of discipline and a lot of C code out there doesn't do it.
  • Strings (and arrays in general) don't carry their sizes around. You have to pass a lot of extra parameters in C to deal with this.
  • Without namespaces you have to manage your global namespace carefully.
    • There's no explicit tying of functions to types as there is with class in C++. You have to maintain a convention of prefixing everything you want associated with a type.
  • You will see a lot more macros. Macros are used in C in many places where C++ has language features to do the same, especially symbolic constants (C has enum but lots of older code uses #define instead), and for generics (where C++ uses templates).

Advice:

  • Consider finding an extended library for general use. Take a look at GLib or APR.
    • Even if you don't want a full library consider finding a map / dictionary / hashtable for general use. Also consider bundling up a bare bones "string" type that contains a size.
  • Get used to putting module or "class" prefixes on all public names. This is a little tedious but it will save you a lot of headaches.
  • Make heavy use of forward declaration to make types opaque. Where in C++ you might have private data in a header and rely on private is preventing access, in C you want to push implementation details into the source files as much as possible. (You actually want to do this in C++ too in my opinion, but C makes it easier, so more people do it.)

    C++ reveals the implementation in the header, even though it technically hides it from access outside the class.

    // C.hh class C {     public:        void   method1();        int    method2();     private:        int    value1;        char * value2; }; 

    C pushes the 'class' definition into the source file. The header is all forward declarations.

    // C.h typedef struct C C;           // forward declaration  void c_method1(C *); int  c_method2(C *);  // C.c struct C {     int    value1;     char * value2; };    
like image 164
quark Avatar answered Sep 21 '22 16:09

quark