Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Pass anonymous struct as parameter in C

I have the following line of c (carriage returns added for readability - they aren't in the code):

#define i2c_write(slave_addr, reg_addr, len, *data_ptr)
    twi_master_write(MPU_TWI, {
        .addr = reg_addr,
        .addr_length = 1,
        .buffer = *data_ptr,
        .length = len,
        .chip = slave_addr
    })

Where twi_master_write() is declared as:

uint32_t twi_master_write(Twi *p_twi, twi_packet_t *p_packet);

and twi_packet_t is declared as:

typedef struct twi_packet {
    uint8_t addr[3];
    uint32_t addr_length;
    void *buffer;
    uint32_t length;
    uint8_t chip;
} twi_packet_t;

The parameters of twi_write() are all required to be of type unsigned char.

When compiling, I receive the following error:

expected expression before '{' token

Is there a correct way to do what I'm trying to do here, or is it just not possible?

like image 662
MTCoster Avatar asked Mar 19 '23 23:03

MTCoster


1 Answers

My take on it, in a compilable sample. This is a compilation stub and will not run correctly, so don't try to run it as-is !

//
// Cobbling up a compilation stub
//

#include <stdint.h>

struct Twi;
typedef struct Twi Twi;

#define MPU_TWI (Twi*)0

typedef struct twi_packet {
    uint8_t addr[3];
    uint32_t addr_length;
    void *buffer;
    uint32_t length;
    uint8_t chip;
} twi_packet_t;

uint32_t twi_master_write(Twi *p_twi, twi_packet_t *p_packet);


//
// Now for my answer :
//

#define i2c_write(slave_addr, reg_addr, len, data_ptr) \
    twi_master_write(MPU_TWI, &(twi_packet_t){         \
        .addr = reg_addr,                              \
        .addr_length = 1,                              \
        .buffer = *data_ptr,                           \
        .length = len,                                 \
        .chip = slave_addr                             \
    })

main()
{
    // Trigger that macro !
    i2c_write(0, 0, 0, (void**)0);
}

This instanciates a compound literal and passes its address to the function. The literal's lifetime does not exceed that of the full call expression.

like image 178
Quentin Avatar answered Mar 23 '23 08:03

Quentin