C++ Quick Tips

Results 1 to 1 of 1
  1. #1
    Hardcore Member ptr0x is offline
    Feb 2011 Join Date

    C++ Quick Tips

    C++ Quick Tips

    I'll use this topic to share some knowledge regarding proper C++ programming as a lot of C++ codes I saw in the community lacks some vital aspects of proper development. I'll start the topic with some basic tips and will updating it while I have time and face new common problems in codes.

    STOP using preprocessors as constant value representation
    This is one of the common mistakes of those who start to learn C++. Using preprocessors like #define to declare constants is just wrong. What will happen when you declare such a definition is that before the compilation occurs in the proprocessing stage, the preprocessor will resolve all preprocessor directives (#pragma, #include, #define, #if, etc) and substitute it with its definition. When you use #define to declare constants this type will probably be removed from the .obj in the compilation process (the same for the .pdb). The preprocessor will substitute every #define for its definition, not create a data type to the value. This will lead to problems like when you are debugging and the code you are stepping through makes use of a #define the debugger will not be able to retrieve (in most cases) the value of the definition (because there isn't a type there, just a constant number). A clean solution to this is use anonoymous enumerations. You can easily (with no further code change) change a #define MAX_USER 10 to enum { MAX_USER = 10 };. This will do exactly what you meant when you declared the #define and will save you from future headaches (that to not mention code quality benefits).

    Treat const functions and const parameters as default in your code
    C++ does not run under a fully managed environment like other languages. This brings some benefits but if you don't take the proper caution your code will be very error prone. I know this one can be tough at the beggining but try to familiarize yourself to always declare functions and its parameters as const, when the compiler complains about a const being evaluated, then you analyse if that type/function really needs to be changed, if so you just remove the const operator for that specific type. It will help you write better code and avoid some problems in the future.

    ALWAYS prefer to use smart pointers rather than native pointers
    I can't stress this enough but I'll try. ALWAYS before thinking about declaring a native pointer, think again to see if there isn't a proper smart pointer to fit your needs with that pointer. I can't talk much about smart pointers here because it would take a lot of text space, but I HIGHLY suggest you take a day or two to read and know better about smart pointers and its uses in C++.

    C++ do have a garbage collector. Make use of it!
    Despite not running under a managed environment, the C++ compiler have a feature for you to easily free resources when they are not needed anymore. This is called RAII (short for Resource Acquision Is Initialization). RAII is a simple rule that the C++ compilers uses to assure every object (that refers to both classes and structs) that goes out of scope will have its destructor called. In other words, always when you implement classes and structs, keep in mind to use the ctor as the function to initialize all needed variables and resources the class need and the dtor to free any resource the class used. If you use this along with the use of smart pointers, your code will be VERY much readable, maintanable and VERY less prone to big problems like memory leak and dangling pointers.

    Do not #include unneeded headers in your header files.
    Take by default the approach to only include a header in another header when there is no other option. This will speed up the linker process and decrease the relation and dependency around .obj's and its headers. Try to always use forward declaration of types (structs and classes) where you can.

    Do not (NEVER) mix C++ code with assembly inline code in naked functions
    A naked function in C++ is a function that lacks stack frame, so it can not have any local variables. This is a common error for those learning patching and are using C++ to build a dll to create hooks in another native code. Usually you make a jump in the target PE to a naked function in your C++ dll to modify the behaviour of that native code. The problem when the naked function have C++ code is that you put yourself in the compiler optmizations to decide whether to compile a code using the stack frame to declare temporary variables or not. When you type complex C++ instructions, the compiler usually optmize that using the function's stack frame to create temporary variables. If that occurs inside a naked function, your innocent C++ instruction will MODIFY the stack frame of the function you are hooking. This can result in this code modifying local variables of that function or if you are lucky enough it will modify the return address or the saved stack frame probably resulting in a process crash. The solution to this is to NEVER (unless you really know what you are doing) put C++ code inside a naked function. If you are using naked functions to access the hooked function stack frame, always put asm inline code in the naked function and inside it you can call another cdecl function where you can code as much C++ as you want.

    Stop using global variables
    Global state in a program breaks a lot of rules of good code. Besides some specific scenarious may force you declar global variables, 99.9% of the cases you don't. When you create a code that depends heavily on global state you are creating a code that is VERY hard to maintain and read. This IS indeed a big deal, trust me. There are some implementation strategies you can use to avoid global state in a program. You can start by taking a read on Dependency Injection (DI).

    This is it for today, if you have a quick tip that is not listed here reply with it and I will update the topic.
    Last edited by ptr0x; 05-09-18 at 09:44 AM.