thinking of the namespace proposal for c, and, i wonder if, we couldn’t have namespaces done in the preprocessor, like:

/* lib.h */
#namespace lib lib_

void lib::foo(); /* declares lib_foo as a function name */

/* app.c */
#include <lib.h>
#using lib::foo
#using lib::foo as nya
#using lib as MyApi

int main(void) {
/* all of those would be pre-processed to lib_foo() */
lib::foo();
foo();
nya();
MyApi::foo();
}

works with macros, and identifiers, basically anywhere a #define would also work

and could be backwards compatible, e.g. if i were to use it in openrc:

/* rc.h */
#ifdef _HAS_NAMESPACE
#namespace rc rc_
#namespace RC RC_
#endif

now older c programs can still use rc_service_resolve, and newer ones can use rc::service_resolve (as well as #using directives)

including whole namespace, like #using lib, could work but it’d be a pain to implement i think, since the preprocessor would need to keep track of all lib_ it sees since #namespace was declared, and forward-replace them

but with or without whole-namespace-inclusion, this has really simple semantics and imo predictable errors, as namespacing conflicts can be reported the same way “redefinition” of macro names are

thinking of the namespace proposal for c, and, i wonder if, we couldn’t have namespaces done in the preprocessor, like:

/* lib.h */
#namespace lib lib_

void lib::foo(); /* declares lib_foo as a function name */

/* app.c */
#include <lib.h>
#using lib::foo
#using lib::foo as nya
#using lib as MyApi

int main(void) {
/* all of those would be pre-processed to lib_foo() */
lib::foo();
foo();
nya();
MyApi::foo();
}

works with macros, and identifiers, basically anywhere a #define would also work

and could be backwards compatible, e.g. if i were to use it in openrc:

/* rc.h */
#ifdef _HAS_NAMESPACE
#namespace rc rc_
#namespace RC RC_
#endif

now older c programs can still use rc_service_resolve, and newer ones can use rc::service_resolve (as well as #using directives)

including whole namespace, like #using lib, could work but it’d be a pain to implement i think, since the preprocessor would need to keep track of all lib_ it sees since #namespace was declared, and forward-replace them

but with or without whole-namespace-inclusion, this has really simple semantics and imo predictable errors, as namespacing conflicts can be reported the same way “redefinition” of macro names are