Follow

I feel like I'm losing my mind; to any C people out there, what is the right way to initialize an empty array in a struct? I keep getting a weird error "expected expression before '{' token" for the line "ctx->comps = {};"

· · Web · 1 · 0 · 0

@flbr Maybe {0} if ctx->comps is an array of ints?

For other types I'm not immediately sure what options C has these days for literal-based initialization.

@flbr Ah, I just remembered this example from a file I spent a lot of time staring at in the past few weeks: github.com/antirez/kilo/blob/6

Basically include one item within the curlies per element of the array. For each item, recursively define structs using nested curlies containing the right number of fields.

@akkartik I'm not 100% sure on this, but it seems that I get the same error no matter what I put in the curly brackets?

@flbr Can you try to create a little test program?

I'll try it as well.

@flbr Here's a simple thing that compiles for me:

struct Point {
int x;
int y;
};

struct Point a[2] = {
{1, 2},
{3, 4}
};

@akkartik not quite related, but what is the significance of declaring a struct like you did versus like this:
"struct Point {
int x;
int y;
} Point;"

@flbr I believe that's declaring a struct type and also the variables of that type at once? Yes, no difference. Mostly just a stylistic thing. I tend to think of types as things I can use over and over again, so don't couple their definitions with variables.

(Part of the reason: all my programs from a certain period of Literate Programming (akkartik.name/post/wart-layers) have type definitions in a separate section from global variables. Makes some refactorings more convenient.)

@akkartik well, this works:

struct Person {
char *name;
int age;
};

struct Test {
int len;
struct Person names[10];
};

struct Test t = {
.len = 0,
.names = {},
};

@flbr You're right, it does! What's the program that doesn't work? One trick I use sometimes is to gradually strip away code from a complex program while constantly checking for presence of the problem.

@akkartik hmm, with the previous test struct definitions, this code fails (though with the different error "expected '=', ',', ';', 'asm', or '__attribute__' before '->' token")

struct Test t;
struct Test *t_ptr = &t;

t_ptr->len = 0;
t_ptr->names = {};

@flbr Ok, I think I see the issue. In C and C++ initializer expressions are a special thing. You can only use them when defining a variable, not in arbitrary assignments.

I know, it sucks :/

@akkartik so what would the correct version of those last 2 example lines be?

@flbr Just define t like you did at first:

struct Test t = {
.len = 0,
.names = {},
};

After you initialize it, define t_ptr based on it.

@akkartik hmm, so is there just no way to change the values of t with t_ptr?

@flbr Oh sure there is. You just have to use less expressive syntax. For example,

strcpy(t_ptr->names, "abc");

Since the struct definition already allocated space for names, you don't want to assign to names. Copy to the space it points at.

@akkartik is there a function which is type-agnostic for copying data to values at pointers?

@flbr memcpy will copy random bytes to random pointers. In general all of C is pretty type agnostic. You can just cast away whatever type to whatever type..

@akkartik back to that original error (from the original post), with the line
"memcpy(ctx->comps, {}, sizeof(Component * NCMPS));" I'm getting the same error, which is... deeply suspicious XD

@akkartik Woo! fixed that at least
with:
"
Component comps[NCMPS];
memcpy(ctx->comps, comps, sizeof(comps));
"

Sign in to participate in the conversation
Merveilles

Revel in the marvels of the universe. We are a collective of forward-thinking individuals who strive to better ourselves and our surroundings through constant creation. We express ourselves through music, art, games, and writing. We also put great value in play. A warm welcome to any like-minded people who feel these ideals resonate with them.