expected expression before '{' token

2020-03-01 16:15发布

问题:

I am getting: "error: expected expression before '{' token" for the line I've commented before. If the struct is already defined why would it need a "{" before token. Thanks for any help you can provide.

struct sdram_timing {
    u32 wrdtr;
    u32 clktr;
};

int calibration(void);
unsigned char read_i2c_cal(void);
static unsigned int eepcal[15];

main() {
    DQS_autocalibration();
}

int calibration(void)
{
    struct sdram_timing scan_list[30];

    read_i2c_cal();
    if(eepcal[0] == 0){

       scan_list = {{eepcal[1], eepcal[2]}, {-1, -1}}; // <-- PROBLEM LINE

        }
        else {
            //foo
        }

    return 0;
}

unsigned char read_i2c_cal(void) {
    eepcal[0] = 0;
    eepcal[1] = 02;
    eepcal[2] = 03;
}

回答1:

The error is because you can't assign an array that way, that only works to initialize it.

int arr[4] = {0}; // this works
int arr2[4];

arr2 = {0};// this doesn't and will cause an error

arr2[0] = 0; // that's OK
memset(arr2, 0, 4*sizeof(int)); // that is too

So applying this to your specific example:

struct sdram_timing scan_list[30];
scan_list[0].wrdtr = 0;
scan_list[0].clktr = 0;

or you could use memset the same way, but instead of sizeof(int) you need size of your structure. That doesn't always work... but given your structure, it will.



回答2:

Arrays in C language are not assignable. You can't assign anything to the entire array, regardless of what syntax you use. In other words, this

scan_list = { { eepcal[1], eepcal[2] }, {-1, -1} };

is not possible.

In C89/90 you'd have to spell out your assignments line by line

scan_list[0].wrdtr = eepcal[1];
scan_list[0].clktr = eepcal[2];
scan_list[1].wrdtr = -1;
scan_list[1].clktr = -1;

In modern C (post-C99) you can use compound literals to assign entire structs

scan_list[0] = (struct sdram_timing) { eepcal[1], eepcal[2] };
scan_list[1] = (struct sdram_timing) { -1, -1 };

Finally, in modern C you can use memcpy and compound literals to copy data to the array

memcpy(scan_list, (struct sdram_timing[]) { { eepcal[1], eepcal[2] }, {-1, -1} },
  2 * sizeof *scan_list);

The last variant, albeit not very elegant, is the closest way to "emulate" array assignment.



回答3:

You can only use an initializer list in the declaration of the variable, not after the fact.



回答4:

Initializer list can only be used to initialize an array. You cannot use it afterwards.

However if you use GCC, you can use Compound Literal extension:

scan_list = (struct sdram_timing[30]){{eepcal[1], eepcal[2]}, {-1, -1}};

You might need to change scan_list type to be struct sdram_timing *