On C++ language flaws

Every programming language has it's flaws. Some people say "C++ fixes problems it created". You cannot say you know a language or tool without knowing it's flaws. That's why I have included some of them below.

List of most important issues for me:

1) Lack of modules

Pascal has units. Python - modules. In C/C++ it's different. They need some additional constructs ("idioms") to perform something that is build-in for other languages.

  • module interface (header) needs header guards to correctly compile caller-side and called-side C++ files
  • module cannot have package-private parts (shared among several classes), you need PIMPL or weaker - "details" namespace for this
    namespace my_net_lib
      int open_connection();
      int close_connection();
      namespace details
        // this part is forbidden to be used outside of library
        int is_proxy_connection();    

Note: there is a proposal to fix module support for C++: WG21 SG2 (Modules)


2) String support is weak

  • strings are supported in two different ways - they can be passed as "const char[]" or "const std::string &"
  • literal as "test" is not a std::string, it's just a "const char[]", so additional processing (copy) is required when you call functions with literals
  • function overload with "void *" argument is selected instead of same function with "std:string" argument when used with literal
  • Unicode support is not complete - see Unicode

3) You need to remember many traps language "provides" for you:

a) function declaration instead of object construction

void foo()
    // declares a function x instead of construction of object x
    List x();   

b) memory leak in derived class because parent class destructor is not virtual

See C++ language feature: virtual destructor

c) enums can contain items with non-unique values

4) Iterators cannot contain polymorphic parts (heap-allocated parts) because:

a) they are passed by value in STL

b) so it slows down performance A LOT

5) Lack of portable library interface

Libraries compiled by different compilers or with different compiler settings cannot be used in the same project. Dynamic libraries make life easier, but you still cannot pass exceptions or std::string from DLL to main program if compiled by another vendor. And dynamic libraries do not support OOP. So you need to use structural programming when implementing API.

Workaround - use DynObj from CodeProject by Arne Steinarson, 2007

6) Undefined behaviour

Term defined for C/C++ - see UB. Can cause errors appearing because of aggressive compiler optimizations, errors that can be detected... by compiler (Clang).

7) at least five ways of passing objects:

  • by value (as iterators)
  • as raw pointer (with "const" it creates 3 ways alone)
  • as smart pointer
  • as reference
  • as const reference

In Java: one way (by reference).