Enhancement request of symbol names resolving
Suppose we have some code which @exports a name and immediately use it via @extern in the same module (!):
import std::io;
extern fn void f(String h) @extern("f");
fn void impl_f(String h) @export("f") => io::printfn(h);
fn void main()
{
f("123");
}
Here is what we have:
/nix/store/wi0nl3i48dl27dalzrrlq4n9a6mrl63y-binutils-2.44/bin/ld: build/obj/linux-x64/main.o: in function `main.main':
/home/starleks/coding/probe/c3-sandbox/main.c3:9:(.text+0x41): undefined reference to `f'
collect2: error: ld returned 1 exit status
Failed to link executable 'build/main' using command 'cc -o build/main -rdynamic -pthread build/obj/linux-x64/std_collections_list.std.os.backtrace.Backtrace.o build/obj/linux-x64/
std.core.ascii.o build/obj/linux-x64/std.core.mem.o build/obj/linux-x64/std.core.string.conv.o build/obj/linux-x64/std.core.mem.allocator.o build/obj/linux-x64/std.core.dstring.o b
uild/obj/linux-x64/std.core.types.o build/obj/linux-x64/std.core.string.o build/obj/linux-x64/std.core.builtin.o build/obj/linux-x64/std.io.file.o build/obj/linux-x64/std.io.os.o b
uild/obj/linux-x64/std.io.o build/obj/linux-x64/std.atomic.o build/obj/linux-x64/std.math.o build/obj/linux-x64/std.math.math_rt.o build/obj/linux-x64/std.os.posix.o build/obj/linu
x-x64/std.os.backtrace.o build/obj/linux-x64/std.os.linux.o build/obj/linux-x64/std.os.process.o build/obj/linux-x64/libc.o build/obj/linux-x64/main.o -ldl -lm'.
And what will be if we swap the definition and declaration in order:
import std::io;
fn void impl_f(String h) @export("f") => io::printfn(h);
extern fn void f(String h) @extern("f");
fn void main()
{
f("123");
}
The second one works:
Program linked to executable 'build/main'.
Launching ./build/main
123
Program completed with exit code 0.
I propose to feed the both cases as correct without needing to order it properly. P.S. The issue is not present if we divide those into two different modules
I understand the linker error and the proposal to make both orders work.
But why would we need @extern to reference a symbol defined in the same module?
Normally @extern is for importing external symbols (e.g. from C).
If the implementation is already in the same module, you can just call it directly.
Supporting an order-independent same-module @extern + @export combination adds compiler complexity for a usage pattern that seems unnecessary outside of specific test scenarios.
I understand the linker error and the proposal to make both orders work. But why would we need
@externto reference a symbol defined in the same module? Normally@externis for importing external symbols (e.g. from C). If the implementation is already in the same module, you can just call it directly.Supporting an order-independent same-module
@extern+@exportcombination adds compiler complexity for a usage pattern that seems unnecessary outside of specific test scenarios.
It's all about consistency. We can just prohibit @extern and @export in the same module. However, it will then cut off the possibility to expand the module with the implementation. Sounds hacky but might be useful - that's why C has retrieved such a success, because of hacky stuff you can do with it (one of many reasons).
Okay. We have to see what @lerno thinks.
There is a related feature, @weak which should work with this but doesn't. I need to reexamine its use.