0

Consider a structure that represents a point in cartesian co-ordinate.

struct point { float x, y; };
typedef struct point point_t;

I have a function that takes in a bunch of points and draws a curve based on the points passed, whose definition looks like this,

void beziercurve(int smoothness, size_t n, point_t** points)

I have written the function bezier and I want to test if my function is working correctly. So, inside the main function, I passed the following dummy values to the function via compound literals,

point_t **p={(point_t*){.x=1.0, .y=1.0},
             (point_t*){.x=2.0, .y=2.0},
             (point_t*){.x=4.0, .y=4.0}};
beziercurve(100, 3, p);

LLVM gives me the following error,

bezier.c:54:44: error: designator in initializer for scalar type 'point_t *'
  (aka 'struct point *')
    point_t** p=(point_t**){(point_t*){.x=1.0,.y=1.0},(point_t*){.x=2.0,.y=2.0...
                                       ^~~~~~

I even tried something like this,

point_t **p={[0]=(point_t*){.x=1.0, .y=1.0},
             [1]=(point_t*){.x=2.0, .y=2.0},
             [2]=(point_t*){.x=4.0, .y=4.0}};
beziercurve(100, 3, p);

But that also doesn't work. My logic is like this: (point_t*){.x=1.0, .y=1.0} creates a pointer to a temporary structure and a bunch of these structure pointers inside squiggly brackets creates an array of those pointers that I can pass to the function.

What am I missing? Why is the code not working?

sigsegv
  • 159
  • 7
  • 1
    *`(point_t*){.x=1.0, .y=1.0}` creates a pointer to a temporary structure* - Pointer does not have fields, so your syntax is simply not valid. You might create a compound literal of the *structure* itself and pass it's address such as `&(point_t){.x=1.0, .y=1.0}` – Eugene Sh. Nov 05 '18 at 16:59
  • @EugeneSh. Can you write the whole array initializtion, please? For me, `point_t** p={&(point_t){.x=1.0,.y=1.0},&(point_t){.x=2.0,.y=2.0},&(point_t){.x=4.0,.y=4.0}};` compiles okay with warning but throws me a SIGSEGV. – sigsegv Nov 05 '18 at 17:05

1 Answers1

1

This compound literal doesn't work:

(point_t*){.x=1.0, .y=1.0}

Because it's trying to say that the initializer {.x=1.0, .y=1.0} is a pointer, but it's not.

To create an array of pointers to structs, you would need to do this:

point_t *p[]={&(point_t){.x=1.0, .y=1.0},
             &(point_t){.x=2.0, .y=2.0},
             &(point_t){.x=4.0, .y=4.0}};

However, I suspect what you actually need is just an array of structs. You could then create it like this:

point_t p[] = {
    {.x=1.0, .y=1.0},
    {.x=2.0, .y=2.0},
    {.x=4.0, .y=4.0}
};

Then you would change your function to take a pointer to a point_t:

void beziercurve(int smoothness, size_t n, point_t *points)
dbush
  • 205,898
  • 23
  • 218
  • 273
  • But in `void beziercurve(int, size_t, point_t*)`, doesn't the last argument take just a pointer to just one structure? – sigsegv Nov 05 '18 at 17:09
  • It's an array, so point_t *points contains the start address of the array. Consecutive point_t s can be accessed like in an array by index [1] i.e – guenni_90 Nov 05 '18 at 17:13