Ted said:
Is the complexity of C++ by design?
Yes. C++ was invented to follow these requirements:
A. be popular and useful by many
B. shred; compete with assembler
C. be useful on very large projects
To hit Requirement A, C++ had to upgrade C, so that C's humongous library of
existing code could compile, with minor tweaks and cleanups, as C++ code.
That permits C++ to inherit C's huge mind-share, as programmers upgrade
their projects to take advantage of C++ features.
Irritatingly, C is a very old system _also_ invented to hit those same
Requirements. So every hack and degeneracy in C that addressed that list,
C++ extended and augmented.
To hit B, both C and C++ obey the principle "you don't pay for what you
don't use". Consider the lowly pointer p. If you dereference it with *p,
both C and C++ will generate machine opcodes that hit that memory location.
The language doesn't add any safety checks that p contains a valid address
of the correct type. If you won't use them (because you write clean code
where p always points correctly), then you don't pay for them.
That freedom adds incredible complexity. C++ has a new system, references,
to do essentially the same logical thing but in a different physical way. So
C++ has two systems, not one, to put a "handle" on an object and pass the
handle around.
To support Requirement C, both C and C++ can compile and link incrementally.
Because the original C link program was poorly written and hard to manage, C
did not have modules like Ruby or Java. It had #include files, to simulate
importing a module. But programmers must write the import directly into .h
files, manually, instead of simply writing procedures and letting the linker
figure out what bits get linked.
On top of this, C and C++ both have many extra systems (bald pointers, class
declarations, typename, file-scope static) to allow programmers to _reduce_
the number of #include files that each source file must reference. All those
systems force a programmer to maintain and balance the dependencies among .h
files, manually, all for the slim benefit of letting a broken linker rapidly
link all the object files that didn't change.
Oh, and C and C++ force you to manage memory manually, without garbage
collection. Requirement B. Don't get clcm started on that one!!!