0

I have problem with aliasing. I have never faced with it before. I am using Eclipse CDT. I read different solutions but I couldn't find the suitable one for me.

I have the warning

dereferencing type-punned pointer will break strict-aliasing rules [-Wstrict-aliasing]

So I have the following peace of code:

timestamp = st0 % 100000000;

for (std::list<struct trace *>::iterator it = frame_list.begin();
     it != frame_list.end();
     ++it) {
  struct my_rtppacket *packet = NULL; 
  packet = new struct my_rtppacket;

  packet->ts = (int32_t)((*it)->time * 1000000);
  packet->seq = count_seq;

  //In the following two strings I have the warnings :(

  *(uint16_t*) (packet->buf + 2) = htons(packet->seq);
  *(int32_t*) (packet->buf + 4) = htonl(packet->ts + timestamp);

  insert_data_to_list(packet); // This function inserts packets to list}
}

As the result there are wrong values in packet->buf + 2 and packet->buf + 4.

Please! Help me to fix this problem!

EDIT I want to understand what was wrong... The structure my_rtppacket is defined in the following way:

{
struct my_rtppacket
{
public:
    my_rtppacket():dump_ts(0), payloadlen(0),packetlen(0),ts(0), seq(0), seq_fr(0), frame_number(0),
    erase(NUM, INIT), path(NUM, INIT), create_time(0), alloc_time(0), before_create(0), sent_flag(0){}
    uint32_t dump_ts;   /*timestamp of RTP dump. It is similar to timestamp of packet generation from the application*/
    int payloadlen;
    int packetlen;
    int32_t ts;         /*timestamp in RTP file*/
    uint16_t seq;       /* Sequеnce number in video sequence*/
    int seq_fr;         /* Sequеnce number in a frame*/
    int frame_number;
    char buf[1600];
    std::vector <path_t> erase;
    std::vector <path_t> path;       //Declare a vector of path_type elements
    char frame_type[10];
    int64_t create_time;
    int64_t alloc_time;
    int64_t before_create;
    int sent_flag;

};

}
  • 3
    That pointer arithmetic, reinterpreting-casts, etc. sure looks shady. However, you would need to provide us with the definition of "struct my_rptpacket" to be sure. – Javier Martín Aug 19 '16 at 09:30
  • I wonder whether a packed struct (or 2 for endianess) would be better. Or maybe creating a function to fill a buffer from the structs data... – Simon Kraemer Aug 19 '16 at 09:48
  • BTW, how do you figure that the values are wrong? – Igor S.K. Aug 19 '16 at 10:08
  • This isn't the problem, but `struct my_rtppacket *packet = NULL; packet = new struct my_rtppacket;` should be `struct my_rtppacket *packet = new struct my_rtppacket;`. Initializing the pointer to `NULL` then immediately assigning a new value to it is pointless. – Pete Becker Aug 19 '16 at 13:10

1 Answers1

2

You should use something like the following to don't break strict aliasing rule:

const uint16_t nseq = htons(packet->seq);
const uint32_t nts = htonl(packet->ts + timestamp);
memcpy(packet->buf + 2, &nseq, 2);
memcpy(packet->buf + 4, &nts, 4);
Jarod42
  • 203,559
  • 14
  • 181
  • 302
  • This solution is ok, however is it possible to check what was written into packet->buf+2? – Ekaterina Pakulova Aug 19 '16 at 10:09
  • @EkaterinaPakulova If you still want to test your way of writing to `packet->buf` use the suggested approach to read back and verify: `memcpy(&nseq_test_var, packet->buf + 2, 2);` – Igor S.K. Aug 19 '16 at 11:16