I’m fairly new to C. I try to write functions for a Vector, but there must be something wrong.
Here’s the code:
/* Defines maths for particles. */
#include <math.h>
#include <stdio.h>
/* The vector struct. */
typedef struct {
long double x, y, z;
} Vector;
Vector Vector_InitDoubleXYZ(double x, double y, double z) {
Vector v;
v.x = (long double) x;
v.y = (long double) y;
v.z = (long double) z;
return v;
}
Vector Vector_InitDoubleAll(double all) {
Vector v;
v.x = v.y = v.z = (long double) all;
return v;
}
Vector Vector_InitLongDXYZ(long double x, long double y, long double z) {
Vector v;
v.x = x;
v.y = y;
v.z = z;
return v;
}
Vector Vector_InitLongDAll(long double all) {
Vector v;
v.x = v.y = v.z = all;
return v;
}
Vector Vector_AddVector(Vector *v1, Vector *v2) {
Vector v3;
v3.x = v1->x + v2->x;
v3.y = v1->y + v2->y;
v3.z = v1->z + v2->z;
return v3;
}
Vector Vector_AddDouble(Vector *v1, double other) {
Vector v2;
v2.x = v1->x + other;
v2.y = v1->y + other;
v2.z = v1->z + other;
return v2;
}
Vector Vector_AddLongD(Vector *v1, long double other) {
Vector v2;
v2.x = v1->x + other;
v2.y = v1->y + other;
v2.z = v1->z + other;
return v2;
}
void Vector_Print(Vector *v) {
printf("X: %Lf, Y: %Lf, Z: %Lf\n", v->x, v->y, v->z); //Before edit: used %ld
}
double Vector_Length(Vector *v) {
return pow(pow(v->x, 2) + pow(v->y, 2) + pow(v->z, 2), 0.5);
}
int main() {
Vector v = Vector_InitDoubleXYZ(2.0, 1.0, 7.0); //Before edit: (2.0d, 1.0d, 7.0d);
Vector_Print(&v);
}
I’m using gcc to compile. Running vector.exe in the commandline gives me the following output:
X: 0, Y: -2147483648, Z: 9650176
and I do not understand why this is happening.
I appreciate any hints (even about my coding-style or whatever could’ve be done better in the code).
Thank you,
The problem (after fixing the various problems if using integer specifiers for floating point formatting) is that you’re mixing GCC types with an MSVC runtime that doesn’t understand them.
First off, MinGW is a GCC compiler, but it uses an MSVC runtime for the bulk of it runtime support. What this means for the
printf()family of functions is that only the format specifiers thatmsvcrt.dllsupports and only the types thatmsvcrt.dllsupports will work. But GCC doesn’t know anything about this, so it’ll pass its own types and, of course, the format specifiers are whatever you pass in the format string (though GCC might issue warnings that don’t really apply to themsvcrt.dllsituation). See Strange "unsigned long long int" behaviour for some examples based on 64-bit ints (I think that newer versions ofmsvcrt.dllmay have fixed some or all of the 64-bit int issues though).The other part of this problem you’re running into is that
long doublein GCC is a different type thanlong doublein MSVC. GCC uses a 96-bit or 128-bit type forlong doubleon x86 or x64 targets (see http://gcc.gnu.org/onlinedocs/gcc/i386-and-x86_002d64-Options.html). However, MSVC uses a 64-bit type – basicallylong doubleis exactly the same asdoubleformsvcrt.dll(http://msdn.microsoft.com/en-us/library/9cx8xs15.aspx):So what this boils down to is that the GCC/MinGW
long doubletype will simply not be compatible with the formatted I/O inmsvcrt.dll. Either switch to usingdoublewith MinGW, or if you need to uselong doubleyou’ll have to cast the values to(double)for formatted I/O or come up with your own formatting routines.Another option might be to use the GCC compiler under Cygwin, which I think will avoid relying on
msvcrt.dllfor I/O formatting (at the cost of relying on the Cygwin environment).