About three years ago I finally realised that all my C++ programmes were grossly over-complicated and enormously time-inefficient to write. Part of this was due to getting carried away with design patterns, refactoring, abstraction layers, and other software engineering busywork that I now believe basically exists as a trap to capture OCD-inclined people and hold them in project purgatory indefinitely. The other part was due to C++ itself. I think that I can summarise my perception thus:
|feature||practical value||time cost|
|declare variables anywhere||extremely high||huge saving|
|boolean data-type||extremely high||large saving|
|single-line comments||very high||saving|
|*& vs. **||high||none|
|inline functions||moderate||very small|
|generic in/out streams||dubious||moderate|
|class private/public sections||none||small|
|try/catch exception handling||none||high|
|getter/setter conventions||none||very high|
|"virtual" anything||none||extremely high|
|templates||the lure of chaos||extremely high|
|time to learn/master||extremely high|
|number of possible styles to read||extremely high|
|allows/vulnernable to bad code||high|
|glut of IDE/compiler-dependent code||moderate|
So what I really want now is to produce things quickly. Now I appreciate low-level simplicity more than abstraction. Fewer, well-chosen features makes a stronger language than a huge variety of features of varying quality and usefulness. How can I get the advantages of C++ without the disadvantages? In the last 3 years I have been experimenting with several styles of C++ and C.
C89, the "default" C on most compilers has a pleasing simplicity but can be rather frustrating when it comes to variable declarations. In 3d graphics, having overloaded operators for vector and matrix data-types is rather handy, and writing functions to do this can be a pain. In pedantic compile mode the compiler will whine if you use single-line comments. You could just leave out the pedantic flag, but would you miss something interesting? C89 is an acceptable solution and writes very portable, concise code, but we are stuck with some tedious relics of the past.
The obvious solution to get most of the best of all worlds is my original style of C compiled with the C++ compiler. We can link-in libraries from C++ which is very handy. We do assume some passive C++ problems though - mangled function headers - so we have to be prepared to use open-source everything or sacrifice portability.
Most C compilers can be coerced into compiling for the C99 standard with a flag like -std=c99 -pedantic-errors. The Internet says this isn't the default because the implementations are still not completed! You can read about the status of C99 implementation in the GCC project at https://gcc.gnu.org/c99status.html. It seems that there are only one or two minor optional features that have been left out there.
C99 offers a collection of features that you probably won't want if you like being in control of low-level code - variable-length arrays, and some extra stuff that's interesting but probably not used that often - complex numbers, but it does have single-line comments, mixed declarations and code, better type casting rules, inline functions, boolean data type via stdbool.h and variations of the standard types of integers and floats for specific memory sizes. You can use the pragma pre-processor directive.
C11 introduces native multi-threading and better Unicode support via char16_t and char32_t, some bounds-checking stuff and file pointers that can open and exclusive-access lock a file. The status of C11 in GCC is https://gcc.gnu.org/wiki/C11Status. You can ask for C11 in GCC ~4.7 and newer with -std=c11. Some of the new features have dubious support in glibc which makes the standard not so attractive for just a few additional low-value features.
I have had the best experiences of all my programming so far with C99. Some limitations I can name are:
Don't take everything as law from your software engineering teachers. If it smells like BS it probably is.