Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Terrible tips for C++ programmers. Part 4

Terrible tips for C++ programmers. Part 4

We're posting more terrible tips for C++ programmers from Andrey Karpov, a C++ expert and the PVS-Studio co-owner and CMO Andrey Karpov.
We hope you have fun and learn something new about how to make your code cleaner.
If these five tips are not enough - here's a link to Andrey's online book of 60 terrible tips: https://pvs-studio.com/en/blog/posts/cpp/1053/

PVS-Studio

October 09, 2023
Tweet

More Decks by PVS-Studio

Other Decks in Programming

Transcript

  1. 60 terrible tips for a C++ programmer Part 4 Tips

    16-20 Andrey Karpov Co-owner and CMO pvs-studio.com
  2. Introduction We are continuing our series of terrible tips for

    C++ programmers with another set of five: tips 16-20. We hope you have a good time reading them. You can view the previous tips in earlier presentations. The tips are a part of an online book by Andrey Karpov. Want to see all tips? Click here: 60 terrible tips for a C++ programmer.
  3. Contents: tips 16-20 • Terrible tip N16. sizeof(int) == sizeof(void

    *) • Terrible tip N17. Don't check what the malloc function returned • Terrible tip N18. Extend the std namespace • Terrible tip N19. Old school • Terrible tip N20. Compact code
  4. The size of int is always 4 bytes. Feel free

    to use this number. The number 4 looks much more elegant than an awkward expression with the sizeof operator. Terrible tip N17. Don't check what the malloc function returned
  5. Terrible tip N16. sizeof(int) == sizeof(void *) The size of

    int is really 4 bytes on many popular platforms. But many – it doesn't mean all! The size of an int can differ significantly. There are systems with different data models. The size of int can be 8 bytes, 2 bytes, and even 1 byte! Formally, here's what can be said about the size of int: 1 == sizeof(char) <= sizeof(short) <= sizeof(int) <= sizeof(long) <= sizeof(long long)
  6. The pointer can just as easily differ from the size

    of the int type and 4. For example, on most 64-bit systems, the size of a pointer is 8 bytes, and the size of the int type is 4 bytes. In old 32-bit programs, developers sometimes stored a pointer in variables of such types as int/unsigned. When such programs are ported on 64-bit systems, errors occur — when developers write the pointer value to a 32-bit variable, the highest bits are lost. Terrible tip N16. sizeof(int) == sizeof(void *)
  7. To read more on this, follow the links: • Pointer

    packing • Fundamental types • What does the C++ standard state the size of int, long type to be? Terrible tip N16. sizeof(int) == sizeof(void *)
  8. It makes no sense to check if memory was allocated.

    Modern computers have a great amount of memory. And if there is not enough memory to complete operations, there is no need for the program to continue working. Let the program crash. There’s nothing more you can do anyway. Terrible tip N17. Don't check what the malloc function returned
  9. If the memory runs out, a computer game can crash.

    It's acceptable sometimes - unless you are participating in a gaming championship. There are other cases when a crash can cause serious damage: 1. The program crashes before it turns off embedded systems 2. The user or CAD systems, databases or video editing systems may lose data or end up with damaged project files. 3. Library developers do not know who will use their libraries. Consequently, they need to account for possible memory allocation errors. For more on this topic, take a look at this article. Terrible tip N17. Don't check what the malloc function returned
  10. Extend the std namespace with various additional functions and classes.

    After all, for you, these functions and classes are standard and basic. Terrible tip N18. Extend the std namespace
  11. The contents of the std namespace is defined solely by

    the ISO committee. In PVS-Studio, the V1061 diagnostic rule is designed to detect these invalid namespace extensions. The next two slides will show which extensions are not valid and which ones are allowed. Terrible tip N18. Extend the std namespace
  12. The ISO standard prohibits adding the following: • Variable declarations;

    • Function declarations; • class/structure/union declarations; • enumeration declarations; • function/class/variable template declarations (C++14). Terrible tip N18. Extend the std namespace
  13. The ISO standard allows adding some specializations of templates defined

    in the std namespace given that they depend on at least one program-defined type: • full or partial specialization of a class template; • full specialization of a function template (up to C++20); • full or partial specialization of a variable template not located in the <type_traits> header (up to C++20). However, specializations on templates located inside classes or class templates are prohibited. Terrible tip N18. Extend the std namespace
  14. Your teammates should know your extensive experience with the C

    language. Don't hesitate to show them your strong skills in manual memory management and in the usage of longjmp. Another version of this tip: smart pointers and other RAII are from evil. Manage all resources manually — this makes code simple and comprehensible. Terrible tip N19. Old school
  15. There’s no reason to refuse smart pointers – they don’t

    require additional processing time (like garbage collection would), they help shorten and simplify code, they reduce a possible risk of a mistake. So why can one often see that all resources are managed manually? 1. Developers may do it out of habit. 2. Reusing the code (that used to be C code) in C++ projects. 3. Fear of overheads. Yes, smart pointers can sometimes have overheads, but they are minor compared to simple pointers. 4. Developers are simply unaware of how, for example, std::unique_ptr can be used. Terrible tip N19. Old school
  16. Use as few curly brackets and line breaks as possible.

    Try to write conditional constructs in one line. This will reduce the code size and make the code compile faster. Terrible tip N20. Compact code
  17. Shortened code is hard to read and contains more mistakes.

    Can you spot an error here? Terrible tip N20. Compact code
  18. PVS-Studio’s diagnostic V560 found that some expressions are always true

    and some are always false. Terrible tip N20. Compact code
  19. If you refactor the code, the error becomes much more

    obvious. The logical NOT (!) operator is applied only to the first subexpression. We just need to add additional parentheses. A more detailed story about the bug is here: How PVS-Studio Proved to Be More Attentive Than Three and a Half Programmers if (!((ch >= 0x0FF10) && (ch <= 0x0FF19)) || ((ch >= 0x0FF21) && (ch <= 0x0FF3A)) || ((ch >= 0x0FF41) && (ch <= 0x0FF5A))) Terrible tip N20. Compact code
  20. I hope you found these tips fun to read –

    and maybe learned something new. In the next presentation we’ll cover tips 21-25. If you want to read all the tips as soon as you can – we’ve posted a complete list of 60 terrible tips here. Conclusion