In C++, the qualifier ‘const’ specifies a compile-time constraint that an object or variable cannot be modified. The compiler verifies that the object or variable never changes and stops you when you try to modify it or re-assign it. However, writing ‘const’ correct code is way more challenging than just using the keyword in some lines, and then allowing the compiler to figure out what makes sense. In this two-part guide, you will get some hints on how to use it properly.

1) Constants defined with the ‘const’  qualifier are best considered as unmodifiable variables with all their properties such as type, size, linkage, and address. Macros, on the other hand, have fewer restrictions because they can expand to any series of tokens (numbers, characters, or strings), but they do not have any of the properties of a variable. Because some macros are defined to expand to numeric literals , they are sometimes thought of as constants, but they’re not. It is the compiler who sees them as _numeric literals, _ despite the fact it does not perform a type-check.

2)** Constant objects are subject to the scoping rules** for all other identifiers, whereas macros are not. Consider the following code:

#define READ_ONLY_VALUE 5

const int read_only_value = 5;
void foo ()
{
    // Only for education purposes. Do not try this at home, kids.
    #define READ_ONLY_VALUE 6 

    const int read_only_value = 6;
    static const int static_read_only_value = 7;
    std::cout<<read_only_value<<std::endl;  
}

It may be seen as obvious that read_only_value is defined twice in this snippet, one time as a global constant variable and another as a local one. When the foo() function is called, it prints the local constant variable with the value of ‘6’. In contrast, READ_ONLY_VALUE is redefined inside the foo() function (which is a bad idea), and that is allowed by the compiler with a warning. That means, the macro just ignores the scope and the symbolic name will be replaced in the object code with the value of ‘6’.

3) Some macros are defined to look like a function call. They are named (no surprise here) function-like macros. This surplus of functionality is in direct contrast to how a constant variable works:

#define MIN(a, b)  ((a) < (b) ? (a) : (b))

Since macros are always expanded by the preprocessor at the pre-compile time, they do not have the overhead of a function call. However, this also the reason why they can not be used for debugging. As mentioned before, they do not follow all the protocols of type-check safety, and because of that, they are more error-prone. The example below portrays the disadvantage of the lack of type checking.

#programming #coding #cpp #software-development #c++ #c++ (iii)

Understanding correctly that messy keyword ‘const’​ in C++ (III)
1.45 GEEK