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.
@Araq
First my apologies for responding so late.
In regards to your comment, I am in fact using a the glm library. Just so as to make sure that no other libraries or Futhark code are used and to facilitate reproducibility, I have created the following repo:
https://github.com/tech4rd/bunny
Here I report my experiments.
The experiments include the original setup that I reported on, and another test were I use the glm code locally. In one of my attempts to reduce the glm code to its bare minimum, the compilation error simply vanished. In the report I provide instructions to test with the local code.
Here is what is interesting. Using the installed library path or the local copy results in different compilation errors. But the error is still a result of Nim generating two types instead of one. More interestingly, when using the package installed library, lines 23:
axis = normalize[3,GLfloat_t](normal)
and 28 fail C compilation (as shown by nimln_)
temp = GLfloat_t(1 - c) * axis0
but line 29 is ok:
temp1 = (GLfloat_t(1) - GLfloat_t(c)) * axis0
What is more, nimsuggest shows the type Vec[3, minimal.GFloat_t] and for line 29 it shows Vec[3, system.float32]. Are these not supposed to be the same? If not, this smacks of a compiler error.
I am assuming that the same code should generate the same errors irrespective of it source path. I am also assuming that if Nim successfully transpiles to C, then the C compiler should never fail. I may be wrong, so correct me.
It would be nice if someone could take the trouble of confirming these results with this repo and the example I provide (takes a few minutes).
TIA
Bump. Can anyone do this quick check?
$:~$ cd /tmp/
$:/tmp$ mkdir test
$:/tmp$ cd test
$:/tmp/test$ git clone https://github.com/tech4rd/bunny.git
$:/tmp/test$ cd bunny/glm_1/
$:/tmp/test/bunny/glm_1$ nimble --verbose run minimal TIA