Hi community,
I am playing around with nim for a couple of days and it's very funny. gorgeous job so far :-)
Now I have a little question about the sizeof operator within a static context:
type tt = tuple [ a: int16 ]
const x = sizeof(int16) # compiles
const y = sizeof(tt.a) # throws the compiler-error: cannot evalutate 'sizeof' because type is not defined completely
const z = sizeof(tt) # throws the compiler-error: cannot evaluate 'sizeof(tt)'
The manual (chapter "const section") says:
3. Procedure calls of the form p(X) are compile-time computable if p is a proc without side-effects (see the noSideEffect pragma for details) and if X is a (possibly empty) list of compile-time computable arguments.
I checked the source and the sizeof proc has the noSideEffect pragma. So, is it a bug? btw, if you do systems programming it's useful not to compute the size of some static objects manually :-)
I am using
Nim Compiler Version 0.13.0 (2016-01-19) [Windows: i386] Copyright (c) 2006-2015 by Andreas Rumpf git hash: a121c3f9eb2a348b9d6ae03ffd01aab26a238c30 active boot switches: -d:release
var v: tt
const y = sizeof(v.a)
Getting the size of a tuple or an object itself probably doesn't work because of different possible alignment, applied to it by a C-compiler, that is, Nim doesn't know, how much bytes a tuple as a whole will occupy.
Hi LeuGim,
thank you for your reply. In case of a raw-type (for instance int8, int16) the compiler should know the size as a whole. If you write tuple [ a: int16, b: int32 ] the tuple is always 6 bytes wide, regardless of your environment. I only expect the error in case of: tuple [a: int 16, b: int]. It's not clear how wide b will be.
mikra: If you write tuple [ a: int16, b: int32 ] the tuple is always 6 bytes wide, regardless of your environment.
No. In fact, on many architectures, the above tuple will be eight bytes in size; it could easily be 16 bytes wide on another. The C standard leaves the amount of padding between and the alignment of struct elements purposely implementation-defined (this can be affected even by command-line options such as -fpack-struct for gcc. It only requires that addresses of non-bitfield elements be in increasing order.
many thanks for the explanation. after almost 20 years of java I forgot that :-)
But nevertheless it should be possible to affect the output c-source (for instance using the c99 type int16_t) and/or using __attribute__((packed)) or mangling a c-macro inside the source for obtaining packed structs (to perform memory mapped IO for instance). Also I could picture a const-definition at the c-compiler-run-level...
What would be the best practice in NIM for that?