Hello,
I am a Nim newbie, so I may be missing something obvious here.
Backstory: I used Furthark to wrap GLFW and OpenGL API. I was able to get a basic example compiling and running. I then installed and tried to use the glm package that provides basic math for vectors and matrices. While setting up a simple "triangle" example, compilation failed with the error that the types are incompatible:
expected ‘tyObject_Vec__77xvYYo1y7cj3XntbSihyg’ but argument is of type ‘tyObject_Vec__HBlNJ9bBJt9ai9cILqwFgnLVw’
I finally tracked this to the following code:
let normal: Vec[3,GLfloat_t] = vec3[GLfloat_t](0.0'f32, 0.0'f32, 1.0'f32)
axis0 = normal * (GLfloat_t(1) / normal.length)
axis = normalize[3,GLfloat_t](normal) Note that compilation fails at the normalize call. This is how it is defined in glm:
proc normalize*[N,T](v: Vec[N,T]): Vec[N,T] = v * (T(1) / v.length) One can see that this should be the same as the line above for axis0. When I do not set the variable type explicitly, nimsuggest shows Vec3[system.float32] for the normal vector. As the code stands above, nimsuggest also shows Vec3[system.float32] for the axis0 vector.
So I followed the error messages and tracked the following types (minimal.nim is the Nim source): /home/hmf/.cache/nim/minimal_d/@mminimal.nim.c
typedef struct tyObject_Vec__77xvYYo1y7cj3XntbSihyg tyObject_Vec__77xvYYo1y7cj3XntbSihyg;
typedef float tyArray__qhrQOb8ydw59aiinXtp9cVKg[3];
struct tyObject_Vec__77xvYYo1y7cj3XntbSihyg {
tyArray__qhrQOb8ydw59aiinXtp9cVKg arr;
};
and /home/hmf/.cache/nim/minimal_d/@mminimal.nim.c
typedef struct tyObject_Vec__HBlNJ9bBJt9ai9cILqwFgnLVw tyObject_Vec__HBlNJ9bBJt9ai9cILqwFgnLVw;
typedef NF32 tyArray__mXNbtvWKAiZn9bWV4uCjiKg[3];
struct tyObject_Vec__HBlNJ9bBJt9ai9cILqwFgnLVw {
tyArray__mXNbtvWKAiZn9bWV4uCjiKg arr;
}; and /home/hmf/.choosenim/toolchains/nim-2.2.6/lib/nimbase.h
typedef float NF32;
I keep staring at this and those 2 types seem to be compatible. After all NF32 is a C float. I am assuming the include is correct because the following is reported during execution:
/home/hmf/.nimble/bin/nim c --colors:on --noNimblePath -d:NimblePkgVersion=0.1.0 --path:/home/hmf/.nimble/pkgs2/macroutils-1.2.0-1759c705ba1fe48426ee7ca2d0c7fa265e91806b --path:/home/hmf/.nimble/pkgs2/futhark-0.15.0-50ab2e44c9d5cc99ba1c85032b63c1086c71371c --path:/home/hmf/.nimble/pkgs2/nimbleutils-0.3.3-9cce152f371ed2277db0bb5853dfe7543c38ac66 --path:/home/hmf/.nimble/pkgs2/termstyle-0.1.0-4641c9f9e587d5cf04ccd3ce0bf1ef0263a16299 --path:/home/hmf/.nimble/pkgs2/glm-1.1.1-4f488f67e5a3c45d3483e1d60a8f52acc8453a8a -o:/home/hmf_x/VSCodeProjects/nim_learn/funim_glfw/bin/examples/glfw/minimal /home/hmf_x/VSCodeProjects/nim_learn/funim_glfw/src/examples/glfw/minimal.nim
Nim Output Hint: used config file '/home/hmf/.choosenim/toolchains/nim-2.2.6/config/nim.cfg' [Conf]
... Hint: used config file '/home/hmf/.choosenim/toolchains/nim-2.2.6/config/config.nims' [Conf]
... Hint: used config file '/home/hmf_x/VSCodeProjects/nim_learn/funim_glfw/config.nims' [Conf]
... ...........................................................................................................................
... For completeness below is the command line executed for C compilation:
'gcc -c -w -fmax-errors=3 -fno-strict-aliasing -pthread -Isrc/glad/include -I/home/hmf/.choosenim/toolchains/nim-2.2.6/lib -I/home/hmf_x/VSCodeProjects/nim_learn/funim_glfw/src/examples/glfw -o /home/hmf/.cache/nim/minimal_d/@mminimal.nim.c.o /home/hmf/.cache/nim/minimal_d/@mminimal.nim.c'
I am at my wits end here. I have tried changing the typing and have not been able circumvent this. Can anyone spot the issue? Is this a gcc bug or flag issue (version 13.3.0)?
Appreciate any help. TIA
I am no C expert, but this small example shows that C compilers don't care that these types are indentical, except the name (there's no type aliasing, atleast implicit):
#include <stdio.h>
typedef float NF32;
typedef struct Vec1 { float arr[3]; } Vec1;
typedef struct Vec2 { float arr[3]; } Vec2;
typedef struct Vec3 { NF32 arr[3]; } Vec3;
Vec1 v1 = {{1.0, 2.0, 3.0}};
Vec2 v2 = {{1.0, 2.0, 3.0}};
Vec3 v3 = {{1.0, 2.0, 3.0}};
void test(Vec1 v) { printf("Good! \n"); }
int main() {
test(v1);
test(v2); // note: expected ‘Vec1’ but argument is of type ‘Vec2’
test(v3); // note: expected ‘Vec1’ but argument is of type ‘Vec3’
return 0;
} @janAkali You are correct.
Which now brings up the question why the Nim compiler generates those 2 definitions of struct. Looking at the C code it seems that only the glm library Vec definition is used.
Thanks for the feedback.
Backstory: I used Furthark to wrap GLFW and OpenGL API
Use existing Nimble packages that wrap these.