Perché sono avvertimenti severi-aliasing generati per questo codice?
-
26-09-2019 - |
Domanda
Ho il seguente codice:
struct A
{
short b;
};
struct B
{
double a;
};
void foo (struct B* src)
{
struct B* b = src;
struct A* a = (struct A*)src;
b->a = sin(rand());
if(a->b == rand())
{
printf("Where are you strict aliasing warnings?\n");
}
}
Sto compilando il codice con la seguente riga di comando:
gcc -c -std=c99 -Wstrict-aliasing=2 -Wall -fstrict-aliasing -O3 foo.c
sto usando GCC 4.5.0. Mi aspettavo il compilatore di stampare l'avviso:
warning: dereferencing type-punned pointer will break strict-aliasing rules
Ma non lo è mai. Posso ottenere l'avvertimento da stampare fuori per altri casi, ma mi chiedo il motivo per cui, in questo caso, non lo è. Non è questo un esempio evidente di infrangere le regole severe aliasing?
Soluzione
docs del GCC per -Wstrict-aliasing=2
dice (sottolineatura mia):
Livello 2: aggressivo, veloce, non troppo preciso. Può avere ancora molti falsi positivi (non come molti come il livello 1 però), e pochi falsi negativi (ma forse più di livello 1) . a differenza di Livello 1, si avverte solo quando un indirizzo è preso. Avverte circa incompleto tipi. Viene eseguito in frontend unico.
Sembra che il codice non è troppo difficile, quindi non sono sicuro che il motivo per cui ci sarebbe un falso negativo, ma forse è perché non si utilizza l'&
operatore di indirizzo per eseguire l'aliasing (che potrebbe essere quello che intende per "avverte solo quando viene preso un indirizzo")
Aggiornamento:
E 'da non utilizzare l'operatore di indirizzo. Se posso aggiungere il seguente codice al file foo.c:
int usefoo(void)
{
struct B myB = {0};
foo( &myB);
return 0;
}
L'allarme viene emesso.
Se usefoo()
è in un'unità di compilazione separata, nessun avviso viene emesso.