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

Programmiersprachen, APIs, Bibliotheken, Open Source Engines, Debugging, Quellcode Fehler und alles was mit praktischer Programmierung zu tun hat.
Antworten
Benutzeravatar
Aramis
Moderator
Beiträge: 1458
Registriert: 25.02.2009, 19:50
Echter Name: Alexander Gessler
Wohnort: 2016
Kontaktdaten:

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

Beitrag 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?
Grinch
Beiträge: 25
Registriert: 16.04.2004, 22:42

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

Beitrag von Grinch »

memset bzw. ZeroMemory sollten relativ unabhängig vom Rest funktionieren.
Benutzeravatar
Schrompf
Moderator
Beiträge: 4858
Registriert: 25.02.2009, 23:44
Benutzertext: Lernt nur selten dazu
Echter Name: Thomas Ziegenhagen
Wohnort: Dresden
Kontaktdaten:

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

Beitrag 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.
Früher mal Dreamworlds. Früher mal Open Asset Import Library. Heutzutage nur noch so rumwursteln.
Benutzeravatar
kimmi
Moderator
Beiträge: 1405
Registriert: 26.02.2009, 09:42
Echter Name: Kim Kulling
Wohnort: Luebeck
Kontaktdaten:

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

Beitrag von kimmi »

Wenn es wie bei Assimp portabel sein sollte, Abstand nehmen von ZeroMemory.

Gruß Kimmi
Benutzeravatar
Krishty
Establishment
Beiträge: 8245
Registriert: 26.02.2009, 11:18
Benutzertext: state is the enemy
Kontaktdaten:

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

Beitrag 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
seziert Ace Combat, Driver, und S.T.A.L.K.E.R.   —   rendert Sterne
Benutzeravatar
Aramis
Moderator
Beiträge: 1458
Registriert: 25.02.2009, 19:50
Echter Name: Alexander Gessler
Wohnort: 2016
Kontaktdaten:

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

Beitrag 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.
Benutzeravatar
Krishty
Establishment
Beiträge: 8245
Registriert: 26.02.2009, 11:18
Benutzertext: state is the enemy
Kontaktdaten:

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

Beitrag 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)
)
seziert Ace Combat, Driver, und S.T.A.L.K.E.R.   —   rendert Sterne
Helmut
Establishment
Beiträge: 237
Registriert: 11.07.2002, 15:49
Wohnort: Bonn
Kontaktdaten:

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

Beitrag 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
Benutzeravatar
Krishty
Establishment
Beiträge: 8245
Registriert: 26.02.2009, 11:18
Benutzertext: state is the enemy
Kontaktdaten:

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

Beitrag 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.
seziert Ace Combat, Driver, und S.T.A.L.K.E.R.   —   rendert Sterne
Antworten