Forum: Compiler & IDEs GCC: warning type-punned pointer


von Ralph (Gast)


Lesenswert?

Wie muss die unten stehende C-Zeile *1 geschrieben werden, damit die 
folgende Warnung nicht mehr Auftritt:

stack.c:73:5: warning: dereferencing type-punned pointer will break 
strict-aliasing rules [-Wstrict-aliasing]

1
 *1
2
3
(*((unsigned long*)&myip[0])) = get_eeprom_value(IP_EEPROM_STORE,MYIP);


'myip' und 'get_eeprom_value' sind wie folgt festgelegt 
(Webserver-Quelltext von U. Radig):
1
unsigned char myip[4];


1
//----------------------------------------------------------------------------
2
//
3
unsigned long get_eeprom_value (unsigned int eeprom_adresse,unsigned long default_value)
4
{
5
  unsigned char value[4];
6
  
7
  for (unsigned char count = 0; count<4;count++)
8
  {
9
    eeprom_busy_wait ();  
10
    value[count] = eeprom_read_byte((unsigned char *)(eeprom_adresse + count));
11
  }
12
13
  //Ist der EEPROM Inhalt leer (0xFF) oder Null (0x00) ?
14
  if (((*((unsigned long*)&value[0])) == 0xFFFFFFFF) || ((*((unsigned long*)&value[0])) == 0x00000000))
15
  {
16
    return(default_value);
17
  }
18
  return((*((unsigned long*)&value[0])));
19
}

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Ich würde statt der wilden Herumcasterei eine union benutzen.

Alternativ sollte mal jemand Herrn Radig mitteilen, dass es auch eine
Funktion eeprom_read_dword() gibt.

von Oliver (Gast)


Lesenswert?

Tja, du könntest entweder mit -WNostrict-aliasing compilieren, dann ist 
die Warnung weg ;), oder du könntest nachlesen, was die Warnung dir 
eigentlich sagen möchte, und dann da mal gründlich drüber nachdenken.

Oliver

von Karl H. (kbuchegg)


Lesenswert?

Probier mal
1
unsigned long get_eeprom_value (unsigned int eeprom_adresse, unsigned long default_value)
2
{
3
  unsigned long value;
4
  
5
  eeprom_read_block( &value, (unsigned char *)eeprom_adresse, sizeof( value ) );
6
7
  if ( value == 0xFFFFFFFF) || value == 0x00000000 )
8
    return default_value;
9
10
  return value;
11
}


Edit:
wobei mir der Cast nach unsigned char * auch noch nicht gefällt. Da 
frage ich mich, warum eeprom_adresse nicht gleich ein derartige Pointer 
in der Argumentliste ist.

: Bearbeitet durch User
von Ralph (Gast)


Lesenswert?

@ Jörg & Karl

Danke für die Infos.

von holger (Gast)


Lesenswert?

Ich hab mir einfach eine Funktion geschrieben die den Kram
umrechnet und dann alle Stellen mit den Warnings ersetzt.
1
//Converts uint8_t array IP to uint32_t
2
uint32_t ToIP(uint8_t *val)
3
{
4
  return ( (uint32_t)val[0] + ((uint32_t)val[1] << 8) + ((uint32_t)val[2] << 16) + ((uint32_t)val[3] << 24) );
5
}

Danach sieht der Code auch schön leserlich aus. Beispiel:

  if( ip->IP_Destaddr == ToIP(myip) )  // if my IP address

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.