Main navigation

Menu
Add To Bookmark

How to avoid bugs using Modern C++


By NIIT Editorial

Published on 27/07/2021

10 minutes

C++ was designed as a general-purpose programming language and has gained popularity over time. Now with modern C++ in the picture, the language has become more object-oriented and generic. However, a major drawback of C++ is that it has a large number of constructions having obscure behaviour. A programmer usually finds them while coding.

Introduction to Modern C++

In simple terms, Modern C++ is a programming language based on C++11, C++14 and C++17. It is an array of idioms and patterns designed to remove the faults of “C with classes”. It offers some important modules like compile-time calculation, lambdas, RAIL, parallelism, etc. Although Modern C++ is all about writing secure codes, there are various errors that come up. This article will focus on those errors and also on the ways by which they can be fixed.

Automatic type inference

This is also known as Type Deduction. It allows the compiler to gather the type of information used for a declaration by procuring it from some connected expression.

The keywords auto and decltype were added to C++. You must already be familiar with their working.

Bug

The following is an example of a 64-bit error:

Bugs

The value of string::npos is usually more than the maximum value of UINT MAX in a 64-bit programme. This value can be designated by a variable of unsigned type. This is where auto comes into the picture. In the above code, the type of the variable n isn’t important, but the fact that it can adjust all the possible values of string::find. The above code can be written using auto to remove the errors:

BugsRemove bugs with c++

Auto won't save us from the integer overflow and there will be less memory allocated for the buffer than 10GiB.

Using auto is not always a permanent solution. Auto isn’t an elixir that can fix all the errors or bugs as many perils are related to its use. For example, auto isn’t of much help when it comes to an incorrectly written loop, as depicted below:

Bugs C++

In the above code, the loop would become an infinity loop for large size arrays. If we re-write the above code fragment with auto, the error would still persist.

C++

 

As explained above, the auto behaves in an unpredictable manner with a simple type. Therefore, it does not work well with additional constructions. Furthermore, since the behaviour is unpredictable, it becomes more difficult to notice the error.

Dangerous countof

An array is considered to be one of the “dangerous” types in C++. Programmers, while passing it to the function, forget that it passed as a pointer and just try to calculate the number of elements with sizeof.

For example:

C++

Warning: The sizeof() operator returns size of the pointer, and not of the array, in 'sizeof (iNeigh_bours)' expression. Vrad_dll disp_vrad.cpp 60

In the above fragment, confusion may arise because of stipulating the size of an array in the argument. This number is just a hint to the programmer and has absolutely no meaning to a compiler. Once this code is compiled, the programmer may not know if something’s wrong. The only solution to rectify the error is to use metaprogramming such as follows:

C++ Bug Removal

The above code could result in a compilation error if we pass to this function instead of an array. The function std::extent was added to C++ even though it isn’t suitable as countof. This is for the simple reason that it returns 0 for inappropriate types.

Bugs

Programmers can make an error with sizeof as well.

Bugs C++

In the above fragment:

·         The operator sizeof() returns the size of the pointer in the ‘sizeof(salt)’ expression and not of the array.

·         If the ‘memcpy’ function is called, it will lead to the underflow of the buffer ‘salt’.

To rectify these errors, the programmer should use std::array: as follows:

Remove bugs with C++

Mistake in a simple ‘for’ loop

The ‘for’ loop is another source of errors.

Remove Bugs with C++

In this fragment, the size of every element in the ‘ARR’ array is not equal to the divisor. This can be fixed by using std::size.

Remove bugs with C++

 

Enum

It is a user-defined datatype used to assign names to the important constants that make a program easily readable and maintainable. The term “enum” is just an abbreviation of the word ‘enumeration’.

The following is an example of a dangerous fragment that was written in C:

Remove bugs with C++

Here, the values of different enum types are compared: switch(ENUM_TYPE_A) {case ENUM_TYPE_B: … }

In this example, one of the named constants is taken from a different enumeration. The error isn’t obvious in the original code because of the lax typing of the enum.

The same isn’t possible in C++, and the programmer will have to use the enum class because the error will show up at the compilation stage. The following code is an example:

Remove bugs with C++

INITIALIZATION IN THE CONSTRUCTOR

Another problem with C++ arises when there is a need to initialize the object in a similar way in different constructors. Let’s discuss a simple situation where there is a class, two constructors and one of them calls the other. So, here’s the pitfall:

Remove bugs with C++

 

In this fragment, the object created wasn’t used. If the programmer needs to call the constructor, the “Guess::Guess(…)” is used. The drawback is in the syntax of the call of the constructor. The programmer forgets this and creates another class instance that is destroyed immediately.

One way to fix this is by explicitly calling the constructor via ‘this’ as follows:

Remove bugs with C++

Virtual Functions

Another problem creator is the virtual functions. They make an error in the signature of the derived class which rather than overriding a function declares a new one. The following is an example of the same:

Remove bugs with C++

In this fragment, there are many arguments but no last argument in the function of heir-class. All these functions are different and unconnected. Such errors usually occur when arguments have a default value.

NULL vs nullptr

Null can be used to specify a null pointer which might result in several unexpected situations. Null is basically a normal macro that expands in 0 having int type:

Remove bugs with C++

Null cannot be used in C++ which is where nullptr comes into picture. nullptr has its own type nullptr_t.

Remove Bugs with C++

va_arg

In certain instances, there is a need to pass an undefined number of arguments. Consider the following fragment:

Remove Bugs with C++

Here, the ‘AtlTrace’ function is not anticipated to receive class-type variables as the third actual argument. What has happened is that the programmer wanted to print the std::wstring string, but he forgot to call the method c_str(). The type wstring will be interpreted as const wchar_t*.

Cairo_status_t

Remove bugs with C++

Narrowing

Another drawback of C++ is that narrowing casts have created havoc in programmer’s lives when shifting to the 64-bit architecture. It is suitable only if there are correct types in the code.

For example, If there are two integer values and the programmer wants to find their ratio:

remove bugs with C++

 

Here, the expression was tacitly cast from ‘int’ type to ‘float’ type. Such errors are bound to happen as there will always be many ways to cast one type to another. But thanks to the new method of initialization in C++11, narrowing casts has been prohibited. The error can be rectified at the compilation stage.

remove bugs with c++

Miscellaneous errors

Apart from the errors mentioned above, there are numerous other ways to make an error in the management of resources and memory.

For example:

Remove bugs with C++

Here, the ‘auto_ptr’ has been used incorrectly, and the class doesn’t have specialization for the arrays because the standard ‘delete’ will be called instead of ‘delete[]’.

In the following fragment, unique_ptr will replace auto_ptr. In addition, it has specialization for the arrays and the ability to pass a deleter functor that will be called instead of delete.

Remove bugs with C++

 

Conclusion

Today, modern C++ offers various instruments that assist you with composing code all the more safely. A lot of developments for order time assessments and checks have shown up.

Yet, there is no procedure or programming worldview that can completely shield you from blunders. Along with the functionalities, C++ likewise gets new bugs, which will be exceptional just to it. This is why we can't exclusively depend on one technique: we ought to consistently utilize the blend of code-audit, quality code, and fair instruments, which can assist with saving your time and caffeinated drinks, the two of which can be utilized in a superior manner. To have a better grasp on the concepts of C++ try out the courses that are offered by NIIT



Advanced Programme in Full Stack Software Engineering

Give your Engineering degree an exceptional touch with NIIT's Pogramme in Full Stack Programming for College Students and stay ahead of your peers!!

College Students of Engineering stream

Top