warning: dereferencing pointer 't' does break strict-aliasing rules
От: Vasya777 Россия  
Дата: 09.03.13 06:12
Оценка:
Здравствуйте, уважаемые специалисты!

Данное предупреждение может привести к неверному присвоению? Что нужно сделать, чтобы его не было?


typedef struct
{
    union
    {
        unsigned char data[8];
        struct
        {
            struct
            {
                unsigned long a1: 1;
                unsigned long a2: 31;
            };
            unsigned long a3;
        };
    };
} test_t;
 
typedef struct
{
    union
    {
        unsigned long b1[2];
        unsigned char b2[8];
    };
} test2_t;
 
void f_test()
{
    test2_t t2 = {{{0, 0}}};
    test_t* t = (void*)&t2;
    t->a1 = 1;
    t->a2 = 1;
    t->a3 = 1;
}


Предупреждения:

main.c:68: warning: dereferencing pointer 't' does break strict-aliasing rules
main.c:67: warning: dereferencing pointer 't' does break strict-aliasing rules
main.c:66: warning: dereferencing pointer 't' does break strict-aliasing rules
Re: warning: dereferencing pointer 't' does break strict-aliasing rules
От: uzhas Ниоткуда  
Дата: 09.03.13 06:26
Оценка:
Здравствуйте, Vasya777, Вы писали:

V>Данное предупреждение может привести к неверному присвоению? Что нужно сделать, чтобы его не было?


рекомендую почитать здесь: http://stackoverflow.com/questions/98650/what-is-the-strict-aliasing-rule
Re: warning: dereferencing pointer 't' does break strict-aliasing rules
От: Шахтер Интернет  
Дата: 09.03.13 11:07
Оценка:
Здравствуйте, Vasya777, Вы писали:

V>Здравствуйте, уважаемые специалисты!


V>Данное предупреждение может привести к неверному присвоению?


Может. Зависит от опций компилятора.

V>Что нужно сделать, чтобы его не было?


Не пользоваться хаками. Используйте битовые операции для упаковки/распаковки чисел.
В XXI век с CCore.
Копай Нео, копай -- летать научишься. © Matrix. Парадоксы
Re: warning: dereferencing pointer 't' does break strict-aliasing rules
От: Vasya777 Россия  
Дата: 12.03.13 16:38
Оценка:
Можно использовать объединения, тогда предупреждений не возникает


typedef union
{
    unsigned char data[8];
    struct
    {
        struct
        {
            unsigned long a1: 1;
            unsigned long a2: 31;
        };
        unsigned long a3;
    };
} test1_t;
 
typedef struct
{
    unsigned long a0;
    union
    {
        unsigned long b1[2];
        unsigned char b2[8];
    };
} test2_t;
 
typedef union
{
    struct
    {
        unsigned char r[sizeof(test2_t) - sizeof(test1_t)];
        test1_t t1;
    };
    test2_t t2;
} testu_t;
 
void f_test()
{
    testu_t t3;
    t3.t1.a1 = 1;
    t3.t1.a2 = 1;
    t3.t1.a3 = 1;
    test2_t t2 = t3.t2;
    t2.a0 = 1;
}


Также если используется глобальный указатель или указатель из аргумента функции, предупреждений не возникает

test2_t* gp_t2;
 
void f_test(test2_t* p_t2)
{
    testu_t t3;
    t3.t1.a1 = 1;
    t3.t1.a2 = 1;
    t3.t1.a3 = 1;
    test2_t t2 = t3.t2;
    t2.a0 = 1;
 
    testu_t* p_t3 = (testu_t*)p_t2;
    p_t3->t1.a1 = 1;
    p_t3->t1.a2 = 1;
    p_t3->t1.a3 = 1;
 
    testu_t* gp_t3 = (testu_t*)gp_t2;
    gp_t3->t1.a1 = 1;
    gp_t3->t1.a2 = 1;
    gp_t3->t1.a3 = 1;
}
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.