In my company, we are using a cross-platform utility library offering a lot of services.
This includes both cross-platform code (e.g. a thread class wrapping either Win32 or pthread API) or every company specific code (e.g. classes to handle proprietary communication protocol between our servers and our clients applications).
We need to deliver part of those features to a client, which agrees to use the same compiler and compiler options than used by the library.
Currently, my design is centered about making sure each version of our library will have its interface be binary compatible with the previous ones:
- Delivering a DLL/SO library
- Using simple and clear naming conventions (inspired by Java camelCaseNaming, etc.)
- Use of the STL
- Use of a global namespace (and prefixing any macros with non ambiguous name to avoid name collision)
- PImpl-ing every classes that needs to be used
- Doxygen-ing everything (and giving the "public part" to the client)
- Simplifying and unifying our interfaces
- No virtual methods in our PImpl classes
- No inlined code unless exception (even constants are exported constant values, defined in the compiled source, and simply declared in the public header)
- Exceptional inline code for utility/indirection functions without much code inside (e.g. the swap function would be inlined, calling the non-inlined swap method of the object it swaps)
- Exceptional inline code for some simple "value classes" without real code, to avoid unnecessary overhead (e.g. a complex number class would be inlined)
- Offering high-level services (calling the PImpl-ed classes described about) through inlined code (meaning the client can reuse/modify it to his own needs)
Is my list complete, or did I miss something which would simplify future maintenance/evolution ?
Is one of my points a mistake ?