tomhrr / dale

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

Unexpected memory layout of variant #206

Closed ChengCat closed 5 years ago

ChengCat commented 5 years ago

I expect variant to be equivalent to the following C program, i.e. payload always starts at the same byte offset.

typedef union {
...
} Data;
typedef struct {
  int type;
  Data data;
} Variant;

But with the following program, it's clear that this is not the case.

(import variant)
(import cstdio)

(def Y (struct intern ((a float) (b float))))

(def-variant X ((A ((x uint64)))
                (B ((x Y)))))

(def dump-hex (fn intern void ((ptr (p uint8)) (n size))
  (for (i \ 0) (< i (cast n int)) (incv i)
    (printf " %02x" (@ (p+ ptr i))))
  (printf "\n")))

(def main (fn extern-c int (void)
  (def X1 (var auto \ (A (cast 1 uint64))))
  (dump-hex (cast (# X1) (p uint8)) (sizeof X1))
  (def X2 (var auto \ (B (Y ((a 1.0) (b 1.0))))))
  (dump-hex (cast (# X2) (p uint8)) (sizeof X2))
  0))

The above program outputs:

 00 00 00 00 00 00 00 00 01 00 00 00 00 00 00 00
 01 00 00 00 00 00 80 3f 00 00 80 3f 00 00 00 00
tomhrr commented 5 years ago

Thanks, this has been fixed.