Why does casting different types of pointers cause a violation of TBAA (type-based analysis)?

I read this blog and then found code that I do not quite understand. Why is this bad code?

float *P;

void zero_array() {
  int i;
  for (i = 0; i < 10000; ++i)
  P[i] = 0.0f;
}

int main() {
  P = (float*)&P;  // cast causes TBAA violation in zero_array.
  zero_array();
}

I hope someone can explain this, please.

+4
source share
2 answers

The following code:

float *P;
P = (float*)&P; 
P[0] = 0.0f;

violates the rule of strict smoothing.

An object Phas an effective type float *because it is its declared type. C11 6.5 / 6:

An effective type of object for accessing its stored value is the declared type of the object, if any.

P[0] , P. (: sizeof(float) == sizeof(float *) . , , !)

P[0] = 0.0f lvalue float float *. 6.5/7:

, lvalue,

"" . " " , float a float *


, . , :

float *Q;
float *P = &Q;
*P = 0.0f;

Q float *, lvalue float.


. , , . P[0] = 0.0f P. , P , - , P - .

P[1] = 0.0f . memset; memset P[1], P[1] P[0] = ....;. .

, , memset, , .


NB. P = (float *)&P . . ( "" ).

+3

, :

for (i = 0; i < 10000; ++i)
    P[i] = 0.0f;
}

:

memset(P, 0, 40000);

, P float, float 4 ( ).

:

P = (float*)&P;

P float. a float * 8 , .

:

int main() {
    int i;

    P = malloc(10000 * sizeof(float));
    zero_array();   // this properly sets an array of 10000 floats to 0.
    free(P);

    float **PP = malloc(10000 * sizeof(float *));
    P = (float *)PP;
    zero_array();    // if sizeof(float *) == 8, the first 5000 pointers will be NULL, 
                     // and the next 5000 will contain garbage.
    free(PP);
}
+1

Source: https://habr.com/ru/post/1618478/


All Articles