Seite 1 von 1

[C++] c‘tor initializer / array zero initialization

Verfasst: 11.05.2010, 09:20
von Aramis
Array–Initialisierung – bislang setzen wir in Assimp in unseren c‘toren explicit alle Arrays auf 0, meist mit einer Schleife. Nach meiner Interpretation des Sprachstandards ist folgendes aber legal:

Code: Alles auswählen

class c {
public:
 c() : mem() {}
private:
  int mem[108];
}
… und sollte das Array auf 0 initialisieren (zero-initialization). VC8 bringt eine nette Warnung die mir mitteilt, dass es genau das tut, aber mit frueheren Versionen nicht getan hat. Na toll, aber irrelevant.

Weiß jemand zufaellligerweise wie es mit anderen Compilern aussieht? Ist meine Interpretation des Standards richtig?

Re: [C++] c‘tor initializer / array zero initialization

Verfasst: 11.05.2010, 09:37
von Grinch
memset bzw. ZeroMemory sollten relativ unabhängig vom Rest funktionieren.

Re: [C++] c‘tor initializer / array zero initialization

Verfasst: 11.05.2010, 10:31
von Schrompf
Ich hab immer std::fill genommen, wenn es darum ging, statische Arrays zu initialisieren. Dynamische Arrays macht man ja immer mit std::vector, außer es muss wirklich ein C-abwärtskompatibles Array sein. Und ein std::vector hat einen Konstruktor, bei dem man den Initialwert aller Elemente übergeben kann.

Re: [C++] c‘tor initializer / array zero initialization

Verfasst: 11.05.2010, 10:42
von kimmi
Wenn es wie bei Assimp portabel sein sollte, Abstand nehmen von ZeroMemory.

Gruß Kimmi

Re: [C++] c‘tor initializer / array zero initialization

Verfasst: 11.05.2010, 10:58
von Krishty
... entweder Schrompfs ::std::fill oder ein eigenes Template ...

Interessanter Punkt, den du da gefunden hast, Aramis ... deine Interpretation ist richtig und da die Zero-Initialization kritisch für statische PODs ist hätte ich nicht gedacht, dass VC 2005 sie nicht unterstützt. Wenn sich die Warnung hingegen auf VC 6 bezieht, drauf gepfiffen ... ich muss auch mit VC 2010 noch in jeder zweiten Initialisierungsliste die Warnung abschalten, dass this benutzt wurde ...

Gruß, Ky

Re: [C++] c‘tor initializer / array zero initialization

Verfasst: 11.05.2010, 12:36
von Aramis
memset bzw. ZeroMemory sollten relativ unabhängig vom Rest funktionieren.
Ich hab immer std::fill genommen, wenn es darum ging, statische Arrays zu initialisieren
Finde ich eher ungeeignet weil du die Array-Bounds extra angeben musst. Dann doch lieber ein Template a la

Code: Alles auswählen

template <typename T, size_t N>
void clear(T (&b)[N]) {
  for (size_t i = 0; i < N; ++i) {
     b[i] = T();
  }
}
… wie von Krishty vermutlich angedacht. Das Problem daran ist, dass es sich dabei, wie bei std::fill, streng genommen nicht um eine Initialisierung handelt :-)
ist hätte ich nicht gedacht, dass VC 2005 sie nicht unterstützt
Doch, VC8 (2005) macht alles richtig:

Code: Alles auswählen

#define MYSIZE 4097

class test {
public:
	test()
		: s()
	{}

	char s[MYSIZE];
};

int _tmain(int argc, _TCHAR* argv[])
{
	test s;
	for (size_t i = 0; i < MYSIZE; ++i) {
		if (s.s[i]) {
			return 1;
		}
	}
	return 0;
}
Bringt:
warning C4351: new behavior: elements of array 'test::s' will be default initialized
Das Beispiel funktioniert aber, das Array wird korrekt initialisiert (was nicht der Fall ist wenn ich den Eintrag im der Initialisierungsliste weglasse). default-initialization hiesse laut Standard aber tatsaechlich, dass keine Initialisierung durchgefuehrt wird. Die Hilfeseite zu der Warnung widerspricht dem:
If the array's element type does not have a constructor, the elements of the array will be initialized with the corresponding zero representation for that type.
… weshalb ich vermute dass hier zwar default-initialization steht, aber in Wahrheit value-initialization gemeint ist. Die wiederrum ist fuer PODs und skalare Typen, wie auch Arrays aus ihnen, aequivalent zur zero-initialization. Ach, verdammte Begrifflichkeiten.

An der Microsoft-Front scheint es also ab VC8 zu klappen. VC7 duerfte, wie VC6, tot sein.

Re: [C++] c‘tor initializer / array zero initialization

Verfasst: 11.05.2010, 13:39
von Krishty
Aramis hat geschrieben:Dann doch lieber ein Template a la … wie von Krishty vermutlich angedacht.
Ich wäre sogar noch einen Schritt weiter gegangen und hätte einfach ::memset() drübergeknattert, wegen POD.
Aramis hat geschrieben:Doch, VC8 (2005) macht alles richtig:
Sauber.
Aramis hat geschrieben:… weshalb ich vermute dass hier zwar default-initialization steht, aber in Wahrheit value-initialization gemeint ist. Die wiederrum ist fuer PODs und skalare Typen, wie auch Arrays aus ihnen, aequivalent zur zero-initialization. Ach, verdammte Begrifflichkeiten.
Ich habe den Standard nicht hier, aber diese Seite sagt: int (und int[]) ist ein integral type ist ein scalar type ist ein POD type und weiter „Default initialization of a POD object [ein Objekt, das von einem POD type ist] is zero initialization [§8.5, ¶5]“ – ob der Standard erst den Zwischenschritt über den Terminus der value initialization geht, kA – die Warnung ist also korrekt formuliert.

(Tatsächlich gilt

Code: Alles auswählen

int * Uninitd = new int; // Beliebiger Wert (no initialization)
int * Initd = new int(); // 0 (default initialization)
, … sehr nützlich zu wissen. Es gibt aber eine abscheuliche Falle:

Code: Alles auswählen

int Uninitd; // Beliebiger Wert (no initialization)
int Initd(); // Keine Variable, sondern der Prototyp einer Funktion!
int Initd = int(); // 0 (default initialization)
)

Re: [C++] c‘tor initializer / array zero initialization

Verfasst: 11.05.2010, 19:01
von Helmut
Folgendes müsste mit C++0x ja theoretisch auch funktionieren:

Code: Alles auswählen

class c {
  int mem[108] = {0};
};
Oder hat es das Feature doch nicht in den Standard geschafft?

Ciao

Re: [C++] c‘tor initializer / array zero initialization

Verfasst: 11.05.2010, 19:02
von Krishty
Das wäre der Königsweg, aber bisher unterstützen es die Mainstream-Compiler noch nicht und Assimp soll außerdem noch ein paar Jahre abwärtskompatibel bleiben.