Well, importing itself can be done easily like this:
{.emit: """
#define HELLO_WORLD 10
""".}
var x {.importc: "HELLO_WORLD", nodecl.}: cint
echo x
This will generate LOC1 = nimIntToStr(((NI) (HELLO_WORLD)));, which directly uses the name. Good.
But what if the user:
x = 20
echo cast[int](addr x)
Nim compiler produces no error for these, and the errors are reported by the C compiler, which looks kinda cryptic.
What I want is, something like:
let x {.importc: "HELLO_WORLD", nodecl.}: cint
where Nim compiler reports errors on modification or taking address of x, while the usage of x generates HELLO_WORLD the symbol instead of 10 the value.
This is a similar issue: https://github.com/nim-lang/Nim/issues/4441
There is a workaround offered in comments that is to import the constant as a procedure instead of a variable:
proc foo(): cint {.importcpp: "FOO@".}