2016-09-21 4 views
0

Рассмотрим этот код:Перетяжка в структуре поплавков

struct Foo { 
    float a, b; 
}; 

void bar(float array[2]) { 
    ... // read array[0] and array[1] 
} 

int main() { 
    Foo foo; 
    bar(&foo.a); 
} 

Является ли этот код безопасным? Скажем, bar доступ к foo.a и foo.b всегда? Мне кажется небезопасным, так как заполнение может происходить, но я не знаю, можем ли мы считать, что заполнение равно 0, так как a и b - float.

+0

Это не определено поведение. Если вы цените дружбу и уважение своих коллег, избегайте. –

+0

Не могли бы вы указать мне на какой-то документ/стандарт? – ChronoTrigger

+0

https://isocpp.org/std/the-standard –

ответ

1

Это более или менее безопасно, потому что нет никаких технических причин для поплавков в структуре, выровненных по-другому, чем в массиве. Но такой код трудно понять: такие трюки с использованием той же памяти, что и разные типы, заставляют вас много думать и отвлекаться от основных вещей в коде. И это действительно никогда не нужно делать. Поэтому лучше избегать таких трюков.

Если я не ошибаюсь, нет официальной гарантии того, что такой код будет работать, так что если вы хотите быть абсолютно безопасным и вам нужно такой код, то вы можете добавить static_assert:

static_assert(offsetof(Foo, b) - offsetof(Foo, a) == sizeof(float)); 
+1

Нет необходимости проверять смещение, потому что ChronoTrigger вызывает панель с адресом, а не адресом структуры. –