Forum Rule: Always post complete source code & details to reproduce any issue!
Results 1 to 4 of 4

Thread: What does this code do/mean.....

  1. #1
    Senior Member
    Join Date
    Apr 2014
    Location
    Cheltenham, UK
    Posts
    109

    What does this code do/mean.....

    Hi,

    I hope someone can help, I am modifying an EByte WiFi-Uart library for Teensy and it includes various forms of this sort of code "Configuration configuration = *(Configuration*) c.data;".
    Can anyone help explain what it means/does.

    Thanks in advance.

    .

  2. #2
    Senior Member brtaylor's Avatar
    Join Date
    Mar 2016
    Location
    Portland, OR
    Posts
    583
    Quote Originally Posted by BriComp View Post
    Hi,

    I hope someone can help, I am modifying an EByte WiFi-Uart library for Teensy and it includes various forms of this sort of code "Configuration configuration = *(Configuration*) c.data;".
    Can anyone help explain what it means/does.

    Thanks in advance.

    .
    Best guess without seeing the whole thing...Configuration is a struct and c.data is an array of chars or unsigned chars. They're casting the data pointed to by c.data to the struct - in other words, populating the struct configuration with data from c.data.

    Here is a trivial example:
    Code:
    struct Example {
      uint8_t a;
      uint8_t b;
      uint8_t c;
      uint8_t d;
    };
    
    uint8_t data[4] = {1, 2, 3, 4};
    
    void setup() {
      Serial.begin(115200);
      while(!Serial) {}
      Example ex = *(Example *)data;
      Serial.println(ex.a);
      Serial.println(ex.b);
      Serial.println(ex.c);
      Serial.println(ex.d);
    }
    
    void loop() {}
    Note, generally this isn't a great practice because you would need to understand the structure packing, which can be platform / compiler specific, but it can be an approach to storing the structure data as an array for writing to something like EEPROM.

  3. #3
    Senior Member
    Join Date
    Jul 2020
    Posts
    174
    Agree. This is a great way to write code that's "accidentally right," so it's best done with care, and only where necessary.

  4. #4
    Senior Member brtaylor's Avatar
    Join Date
    Mar 2016
    Location
    Portland, OR
    Posts
    583
    Quote Originally Posted by Pilot View Post
    Agree. This is a great way to write code that's "accidentally right," so it's best done with care, and only where necessary.
    Just to add on to what Pilot is saying, when I've had a need to do similar operations in the past, and when I was reasonably certain that structs were ordered in a way such that they would be packed correctly, I've used static_assert as a method to check that my assumption was correct, i.e.:

    Code:
    struct Example {
      uint8_t a;
      uint8_t b;
      uint8_t c;
      uint8_t d;
    };
    
    uint8_t data[4] = {1, 2, 3, 4};
    
    static_assert(sizeof(Example) == sizeof(data), "Size mis-match");
    
    void setup() {
      Serial.begin(115200);
      while(!Serial) {}
      Example ex = *(Example *)data;
      Serial.println(ex.a);
      Serial.println(ex.b);
      Serial.println(ex.c);
      Serial.println(ex.d);
    }
    
    void loop() {}
    The assert will fail and the code won't compile if the struct is packed such that the size isn't equal to the array size (i.e. violating my assumption about the packing). The static assert is awesome because it is checked at compile time, so you don't risk any runtime overhead checking that it's true.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •