tomhrr / dale

Lisp-flavoured C
BSD 3-Clause "New" or "Revised" License
1.02k stars 48 forks source link

Confusing semantics of (var extern type) #203

Closed ChengCat closed 3 years ago

ChengCat commented 5 years ago
(import cstdio)
(def x (var extern int))
(def main (fn extern-c int (void)
  (printf "%d\n" x)
  0))

I expect x is defined in this module with an uninitialized value. But the compiler complains about missing symbols instead.

undefined reference to `x'

I expect extern variables have the same semantics with extern structs and functions, i.e. defined in the module and visible to other modules.

tomhrr commented 5 years ago

Thanks for this. There wasn't documentation for this (now updated), but the semantics here are intentionally the same as in C:

$ cat test.c
#include "stdio.h"

extern int x;

int main(void)
{
    printf("%d\n", x);
    return 0;
}
$ cc test.c
/usr/bin/ld: /tmp/ccUQRZFe.o: in function `main':
test.c:(.text+0x6): undefined reference to `x'
collect2: error: ld returned 1 exit status
ChengCat commented 5 years ago

C needs this semantics because C doesn't have the concept of modules. In C, to use global variables from another compilation unit, an extern variable declaration must be used. We don't seem to need this semantics for usual Dale variables, because we could just import that library.

Is there something I missed, that makes this semantics consistent to C is important?

tomhrr commented 5 years ago

The C consistency is mainly to limit surprise for people who are used to C, and to allow people to use C-like approaches to things if that's what they'd prefer. There are some exceptions to this, like the general lack of implicit casting, but it's mostly very similar. I think the arguments in favour of C consistency here are compelling:

ChengCat commented 5 years ago

The C consistency is mainly to limit surprise for people who are used to C, and to allow people to use C-like approaches to things if that's what they'd prefer.

I think this sentence expresses your intention very well, and now I can understand it.

I have been always finding the various kinds of linkage of Dale confusing. The confusion seems to come from the interaction between C linkage and the module system, but I am not sure what to suggest now. I am going to use Dale more, and to give this issue more thought.