Importc work as expect
{.emit: """
typedef struct {
} A;
typedef struct {
A a;
} B;
typedef struct {
B b;
int v;
} C;
""".}
type
A {.importc, inheritable.} = object
B {.importc.} = object of A
C {.importc.} = object of B
echo A.sizeof # 0
echo B.sizeof # 0
echo C.sizeof # 4
Size of new root object type also reasonable, since there are type information at start
type
X {.inheritable.} = object
Y = object of X
Z = object of Y
v: int
echo X.sizeof # 8
echo Y.sizeof # 8
echo Z.sizeof # 16
Compare to C++
class E {};
class F : public E {};
class G : public F {
private:
int v;
};
#include <cstdio>
int main()
{
// 1, 1, 4
printf("%lu, %lu, %lu\n", sizeof(E), sizeof(F), sizeof(G));
}
The size of pure new root object type feel kind of weird
type
O {.inheritable, pure.} = object
P = object of O
Q = object of P
v: int
echo O.sizeof # 1
echo P.sizeof # 1
echo Q.sizeof # 16
Since there are a char embed in O in generated C code, after align, Q become 16 bytes, but the first 8 bytes are wasted. Is it possible to +1 if sizeof get 0 while allocating memory?
I think Nim need to put char member to struct because if struct has no named members, the behavior is undefined in C. https://stackoverflow.com/questions/53952097/empty-structs-in-c
But C++ and gcc allow empty struct. https://gcc.gnu.org/onlinedocs/gcc/Empty-Structures.html
Something like empty base optimization in C++ is not yet implemented in Nim? https://en.cppreference.com/w/cpp/language/ebo
Tow more tests.
Object composite in nim
type
X {.pure.} = object
Y {.pure.} = object
Z {.pure.} = object
x: X
y: Y
echo X.sizeof # 1
echo Y.sizeof # 1
echo Z.sizeof # 2
In C++
class E {};
class F {};
class G {
E e;
F f;
};
class H: public E, public F { };
#include <cstdio>
int main()
{
// 1, 1, 2, 1
printf("%lu, %lu, %lu, %lu\n", sizeof(E), sizeof(F), sizeof(G), sizeof(H));
}
OK, now I might know why nim implement this way. If nim compile only report the size of empty object type as 1 without add a char to generated struct, although it solve the sizeof issue, but when the empty object type embed into other object type, it must at least 1 byte to distinguish with other fields, and this is hard to solve both issue the same time in C.