C++ : My Personal Preferences
Introduction
C++ is complex language since it tries to be backward compatible with old C. So, as C++ adds more features ( syntax/semantics) but it does not remove any old one, even when they are aware that they should not be used. Here I list some of the features that I prefer one over the other. BTW, I am not a expert in C++. My objective is not to be good in a language. Rather, I want to know what is not good and avoid using the same. It is like working hard not be an expert yet write good code that can be understood and can survive/evolve as business continues.
Never use
struct
. Instead, useclass
. Class supports the POD (Plain Old Data Type, which is semantically equivalent tostruct
). So, when our need is pure struct, just use class with POD.Never use raw pointers. Instead go with Unique pointers
Assume, you have a variable, one that holds statically allocated to dynamically allocated memory. You want to to assign this to another variable. While do this, we typically use simple = operator. Instead of this, use
move
semantics. (Recollect the Barrow checker of Rust. Does sound familiar?)Do not use
NULL
. Instead use thenullptr
. (this is of type nullptr_t )Avoid using auto or type inference. We want to be as explicit as possible w.r.t to types.
Do not use
enum
. Instead useenum class
Be specific about int or char sizes. Do not use
int
. instead use types such asint32_t, uint32_t, int64_t
etc. Same is for chars.If you can do fractional operations using fixed point notation, you fixed point notation as such does not use floating point processor. I think, fixed point operations happen in interger processor. This is much faster.
Do not use
malloc()/free()
. Usenew/delet
e. new/delete are strict interms of type, while malloc/free are not. Strangely, while deleting dynamic memory allocated with array, we have to use [] while deleting. Forgetting this does not yield any compiler error, thought is possible. It results in strange memory errors during runtime. ie Do not forget to delete likedelete [] ptr
;Always use uniform initialization for initialization. Do not use = or some other ways to initialize variables.
Use Trailing return type for function return type. The whole return type can be omitted using auto for most cases, I think it is not good as we like to be explicit. Given this, using trailing return type makes our code much like Python or Rust or Type Script as far as function return type declaration is concerned.
Define functions such that it takes exactly one parameter of a class. That class should be explicitly defined for input parameter. Also return type of function should be of a class if it is returning more than one type.
Use move semantics. Though I never coded in Rust. Move semantics should bring the life time safety feature into C++.
Avoid using
cout
. Instead use format class for the same. (something like Python’s f-strings can be a life saver in C++)Avoid using complicated inheritances.
Global constructors gets executed before main() gets called. Avoid using defining global constructors because, if there is any crash, it will be hard to debug. (console initialization happens just before main. So we can’t even log anything in such constructors)
C++ Language is an abstraction over Assembly language. Over engineering in use of C++ can cause more pain than gain.
References
https://en.wikipedia.org/wiki/C%2B%2B11#