why are many procs annotated with "rtl, extern: "nos$1" (or similar) ?
is this only useful for windows?
is there a better way, where this could be automatically done in a more robust way? in particular, the name
This can cause other issues, eg
couldn't that be done automatically by compiler since it could just use mangling instead?
here the error was different, it makes code that relies on map not work because, depending on compiler flags (or, when ran on appveyor), the symbol becomes cdecl, hence doesn't work with map
It's not Windows specific. Name mangling needs to be controlled by the library author if you care about names that make at least some sense for foreign languages like C.
Stdlib authors need to know slightly more than Nim library or application developers, I don't think it's too bad. But if you have concrete ideas of how to improve the situation, I'm listening.
so the main reason is to avoid mangled names when exposing Nim functions (eg via shared library or static link library) to a C (or C-like) program that would call Nim code via extern "C"?
eg:
os/mylib.nim:
proc foo1()=discard
proc foo2() {. extern: "nos$1" .} =discard
proc foo2(a:int) {. extern: "nos$1a" .} =discard
util.cpp:
extern "C" void foo1_9c8JPzPvtM9azO6OB23bjc3Q();
extern "C" void nosfoo2();
extern "C" void nosfoo2a(int64_t a);
int main(){
foo1_9c8JPzPvtM9azO6OB23bjc3Q();
return 0;
}
os/mylib.nim:
proc foo1() # mangle as usual
proc foo2(a:int) {. extern: "nos$1a" .} # mangle as we currently do, via nosfoo2a
proc foo2(a:int) {. extern2 .} # mangle as mylib_foo2 (**makes common case simple**)
# for overloads:
proc foo2(a:int) {. extern2: "mysuffix" .} # mangle as mylib_foo2mysuffix
(the word extern2 can be a better name, note that we could also define via extern: "$0mysuffix" where $0 means mylib_foo2 but I want to make this syntax as simple as possible, especially for common case of no overload)
when debugging (eg through gdb, lldb), using demangling should be ok even without extern pragma