- all bindings declared on the top-level of a file exist for all following code, even when the declaring file is included
- included library code cannot hide helper code and internal code like type definitions and macros. it is difficult to build shareable independent utility libraries as c code, because among type declarations, macros, variable and function names, something is going to conflict or shouldnt be exported
- cant rename bindings on import. for example, if they are named too generically
- only alternative is prefixing, which leads to long identifiers
- any code before inclusion may affect any following included library
- tiny libraries are less practical because of the overhead of building shared libraries
renaming bindings is not possible as any alias requires a reference to the aliased in scope.
if c had namespaces, there might be less need for binary modules, as c code could be included without conflict. this would be similar to other languages like javascript, where modules are just included code.
current options
- no option, wait till one day it is added to the c standard
- compile as cpp and use its namespace syntax. see also dotc
- parse c and its preprocessor, add namespace syntax by rewriting identifier names at definition and places of use - hide unexported bindings, eventually rename exported bindings
- compile a shared library binary object and use a header file and linker to use it in other code. this is the currently common practice for modularising c code. clang modules also work like this. limiting exports from a shared library needs an extra exports file or code annotations. all exports, including exposed types, have to be declared in the header file and users cant rename them without changing the source. does not fully solve the problem because everything that is in the header file can conflict