Jaki jest właściwy sposób zainicjowania bardzo dużej struktury?

W naszym kodzie mieliśmy kiedyś coś takiego:

   *(controller->bigstruct) = ( struct bigstruct ){ 0 };

To kiedyś działało świetnie, a potem zaktualizowaliśmy wersje GCC i nagle zaczęliśmy widzieć przepełnienia stosu. Patrząc na zespół, stary kod GCC (2.x) w zasadzie to robił:

memset(controller->bigstruct, 0, sizeof(struct bigstruct));

Robiło to nowe GCC (3.4.x)

   struct bigstruct temp = { 0 };
   controller->bigstruct = temp;

Po zapoznaniu się ze specyfikacją C99, widziałem dlaczego; C99 zasadniczo wymaga, aby na stosie istniały anonimowe struktury. To dobry pomysł, ale ta struktura miała 4 megabajty i zawsze istniała tylko na stercie!

Uciekliśmy się do stworzenia naszej własnej funkcji „initialize”, która jawnie ustawia członków, ale to brzydki i utrzymujący się ból głowy. Nie uważam memset za właściwe rozwiązanie, ponieważ nie mogę wiedzieć, że wartość bitowa 0 jest odpowiednią wartością zerową dla tego typu (wiem, wybieram, ale tam jesteś; nie przeszkadza mi to kompilator to robi, bo tomogą wiedzieć )

Co to jest „poprawny”, a przynajmniej najlepszy sposób na zainicjowanie tak dużej struktury?

Aby wyjaśnić, dlaczego memset nie jest rozwiązaniem: reguły inicjalizacji elementów, które nie zostały jawnie zainicjowane, są takie same jak inicjowanie statyczne i są następujące: - Jeśli ma typ wskaźnika, jest inicjowany na wskaźnik zerowy; - Jeśli ma typ arytmetyczny, jest inicjowany na (dodatni lub niepodpisany) zero; ...

„memset” ustawi pamięć na wzór bitowy zero, co niekoniecznie jest tym samym. Wyobraź sobie system, który nie używa liczb zmiennoprzecinkowych IEEE. Nietypowe, ale obsługiwane przez C. Reprezentacja 0.0 nie musi oznaczać „zero bitów”, może to być coś wygodnego dla procesora.

questionAnswers(5)

yourAnswerToTheQuestion