;;;; A string literal handed to a declare-c goes to C uncopied; any other string ;;;; is copied and terminated. ;;;; ;;;; basename is bound for the pointer it returns, which for a name with no ;;;; slash in it is the pointer it was given: the literal's own address in the ;;;; program image for the first call, and the wrapper's stack buffer for the ;;;; second, whose string is a local and gets the copy. The two are far apart ;;;; only when the literal was not copied. ;;;; ;;;; puts then shows the bytes C read: the literal, the empty literal, and a ;;;; sub-view that has no NUL after it and so must still be copied. ;;;; ;;;; c-where2 is the same question through a signature with a struct in it, ;;;; which the shim answers with a Flan wrapper over a flattened declaration: ;;;; the literal has to pass through that wrapper. It binds glibc's POSIX ;;;; basename, which answers the same pointer and ignores the extra argument. (defstruct Ch [c i32]) (declare-c c-where [s string] i64 "basename") (declare-c c-where2 [s string c Ch] i64 "__xpg_basename") (declare-c c-puts [s string] i32 "puts") (defn far? [a i64 b i64] bool (let [d (- a b)] (> (if (< d 0) (- 0 d) d) 1048576))) (defn main [] i32 (let [s "hello"] (println (far? (c-where "hello") (c-where s))) (println (far? (c-where2 "hello" (Ch {.c 104})) (c-where2 s (Ch {.c 104})))) (c-puts "hello") (c-puts "") (c-puts (string (slice (bytes-view "hello world") 0 3)))) 0)