[C++] Array unbekannter Größe statisch initialisieren
- Krishty
- Establishment
- Beiträge: 8350
- Registriert: 26.02.2009, 11:18
- Benutzertext: state is the enemy
- Kontaktdaten:
[C++] Array unbekannter Größe statisch initialisieren
Hi,
Ich habe ein Array Type const array[], das static const initialisiert werden soll. Das steckt aber in einer struct. In einer Klasse darf man keine Arrays unbekannter Größe benutzen. Logisch. Also in einen Zeiger umwandeln:
struct Data { Type const * ptr; };
Wie kriege ich das jetzt initialisiert?
static Data const foo = { { { 1 }, { 2 }, { 3 } } }; // error: cannot convert from 'int' to 'Type const *'
(Die Klammern habe ich ja auch nur zum Spaß da hingeschrieben, du dumme Syntaxamöbe eines Compilers)
Unter C99 würde ich ja schreiben:
static Data const foo = { .ptr = { { 1 }, { 2 }, { 3 } } }
Aber das geht ja im tollen C++ nicht -.-
Gibt es da wirklich keine andere Möglichkeit als eine Zwischenvariable?
static Type const fooArray[] = { { 1 }, { 2 }, { 3 } };
static Data const foo = { fooArray };
Gruß, Ky
Ich habe ein Array Type const array[], das static const initialisiert werden soll. Das steckt aber in einer struct. In einer Klasse darf man keine Arrays unbekannter Größe benutzen. Logisch. Also in einen Zeiger umwandeln:
struct Data { Type const * ptr; };
Wie kriege ich das jetzt initialisiert?
static Data const foo = { { { 1 }, { 2 }, { 3 } } }; // error: cannot convert from 'int' to 'Type const *'
(Die Klammern habe ich ja auch nur zum Spaß da hingeschrieben, du dumme Syntaxamöbe eines Compilers)
Unter C99 würde ich ja schreiben:
static Data const foo = { .ptr = { { 1 }, { 2 }, { 3 } } }
Aber das geht ja im tollen C++ nicht -.-
Gibt es da wirklich keine andere Möglichkeit als eine Zwischenvariable?
static Type const fooArray[] = { { 1 }, { 2 }, { 3 } };
static Data const foo = { fooArray };
Gruß, Ky
- Sternmull
- Establishment
- Beiträge: 264
- Registriert: 27.04.2007, 00:30
- Echter Name: Til
- Wohnort: Dresden
Re: [C++] Array unbekannter Größe statisch initialisieren
Du könntest das Array als String Literal schreiben und dessen Adresse in den Zieltyp casten :)
Aber im Ernst: Auch wenn Deine Lösung nicht so schön ist wie sie sein sollte... es lässt sich doch damit leben.
Aber im Ernst: Auch wenn Deine Lösung nicht so schön ist wie sie sein sollte... es lässt sich doch damit leben.
- Krishty
- Establishment
- Beiträge: 8350
- Registriert: 26.02.2009, 11:18
- Benutzertext: state is the enemy
- Kontaktdaten:
Re: [C++] Array unbekannter Größe statisch initialisieren
Ja, für eine einzelne Instanz. Leider muss ich tausend dieser Instanzen in einem Array initialisieren. Tausend Zwischenvariablen zu deklarieren, jede einzeln einzutragen und dieses Monster auch noch zu warten ist …
… okay; ich merke mitten in dem Satz, das das voll und ganz nach etwas klingt, was ich tun würde. Aber nur, wenn es echt nicht anders geht.
Das mit dem String-Literal habe ich mir auch schon überlegt – aber da das Daten-Layout noch nicht final ist, würde jede Änderung an der Datenstruktur (man bedenke u.a. auch Padding des Compilers!) den String unbrauchbar werden lassen. Es ist zum heulen.
… okay; ich merke mitten in dem Satz, das das voll und ganz nach etwas klingt, was ich tun würde. Aber nur, wenn es echt nicht anders geht.
Das mit dem String-Literal habe ich mir auch schon überlegt – aber da das Daten-Layout noch nicht final ist, würde jede Änderung an der Datenstruktur (man bedenke u.a. auch Padding des Compilers!) den String unbrauchbar werden lassen. Es ist zum heulen.
- Sternmull
- Establishment
- Beiträge: 264
- Registriert: 27.04.2007, 00:30
- Echter Name: Til
- Wohnort: Dresden
Re: [C++] Array unbekannter Größe statisch initialisieren
Ist der ganze Ansatz denn wirklich notwendig? Was spricht dagegeben die Daten in eine Datei zu schreiben und dann dort raus zu lesen?
- Krishty
- Establishment
- Beiträge: 8350
- Registriert: 26.02.2009, 11:18
- Benutzertext: state is the enemy
- Kontaktdaten:
Re: [C++] Array unbekannter Größe statisch initialisieren
Dass das noch langsamer wäre als sie erst zu initialisieren.
Mir wurde gerade ein interessanter Vorschlag gemacht: Ein Element pro Zeile initialisieren, dabei die erste und letzte Zeilennummer per Makro speichern und in ein static_assert() packen. Mal gucken, ob ich das hinkriege.
Mir wurde gerade ein interessanter Vorschlag gemacht: Ein Element pro Zeile initialisieren, dabei die erste und letzte Zeilennummer per Makro speichern und in ein static_assert() packen. Mal gucken, ob ich das hinkriege.
- Chromanoid
- Moderator
- Beiträge: 4286
- Registriert: 16.10.2002, 19:39
- Echter Name: Christian Kulenkampff
- Wohnort: Lüneburg
Re: [C++] Array unbekannter Größe statisch initialisieren
Schon mal über einen Code Generator, der aus Dateien in einem precompile step entsprechenden Code generiert, nachgedacht?
- Sternmull
- Establishment
- Beiträge: 264
- Registriert: 27.04.2007, 00:30
- Echter Name: Til
- Wohnort: Dresden
Re: [C++] Array unbekannter Größe statisch initialisieren
Warum muss das langsamer sein? Wenn man die Daten per Memory Mapped file einliest, und die da drin schon das richtige Layout haben, dann dürfte es doch die gleiche Performance haben als würde man sie aus dem Binary lesen.
- Krishty
- Establishment
- Beiträge: 8350
- Registriert: 26.02.2009, 11:18
- Benutzertext: state is the enemy
- Kontaktdaten:
Re: [C++] Array unbekannter Größe statisch initialisieren
Man muss die Datei aber erst öffnen, und das bedeutet: Ab in den Kernel, den die Datei suchen lassen, Rechte prüfen, währenddessen auf die HDD warten, HANDLE reservieren, zurück zur Anwendung. Dann wieder ab in den Kernel, irgendwas machen, was eigentlich nur Anwendungen brauchen, die häppchenweise mappen wollen (nämlich CreateFileMapping()), HANDLE reservieren, zurück zur Anwendung. Dann wieder Kernel, Seite suchen, Seite reservieren, zurück zur Anwendung. Und beim ersten Zugriff dann: Seitenfehler, Kernel, auf die HDD warten, weitermachen. Und eine Indirektion mehr, weil ich jetzt zu einer unbekannten Adresse springen muss.
Dazu dann meinerseits Quelltext, um zu verarbeiten, falls die Datei nicht existiert oder fehlerhaft ist.
Ganz genau dafür ist das Datensegment der Exe da. Die Exe wird ja sowieso gemappt und eingelesen, da kann man sich den ganzen Scheiß auch sparen und liest einfach ein paar KiB mehr.
Nicht zuletzt: Ich schreibe in meinem Projekt nicht bloß Integer, sondern Datenstrukturen. Ich bräuchte also erstmal einen Parser, der mir die menschenlesbaren Initialisierungsdaten in eine binäre Datei umwandelt, wenn ich was an der Datenstruktur ändere (nobody's perfect). Davon habe ich auch schon zu viele. Und genau für sowas sollte eigentlich der Compiler da sein: Array definieren, enums/floats/ints/Strings reinschreiben, wie man lustig ist, fertig.
Wenn diese Dreckssprache nicht einfach mit Nullen auffüllen würde, statt einen Fehler zu melden. Das ist doch wirklich so archetypisch. Irgendeine vollkommen ahnungslose Amöbe meinte 1978, dass es toll wäre, wenn sie zwei Nullen weniger im Quelltext schreiben dürfte und dafür muss ich jetzt leiden.
Dazu dann meinerseits Quelltext, um zu verarbeiten, falls die Datei nicht existiert oder fehlerhaft ist.
Ganz genau dafür ist das Datensegment der Exe da. Die Exe wird ja sowieso gemappt und eingelesen, da kann man sich den ganzen Scheiß auch sparen und liest einfach ein paar KiB mehr.
Nicht zuletzt: Ich schreibe in meinem Projekt nicht bloß Integer, sondern Datenstrukturen. Ich bräuchte also erstmal einen Parser, der mir die menschenlesbaren Initialisierungsdaten in eine binäre Datei umwandelt, wenn ich was an der Datenstruktur ändere (nobody's perfect). Davon habe ich auch schon zu viele. Und genau für sowas sollte eigentlich der Compiler da sein: Array definieren, enums/floats/ints/Strings reinschreiben, wie man lustig ist, fertig.
Wenn diese Dreckssprache nicht einfach mit Nullen auffüllen würde, statt einen Fehler zu melden. Das ist doch wirklich so archetypisch. Irgendeine vollkommen ahnungslose Amöbe meinte 1978, dass es toll wäre, wenn sie zwei Nullen weniger im Quelltext schreiben dürfte und dafür muss ich jetzt leiden.
- Sternmull
- Establishment
- Beiträge: 264
- Registriert: 27.04.2007, 00:30
- Echter Name: Til
- Wohnort: Dresden
Re: [C++] Array unbekannter Größe statisch initialisieren
Was bitteschön machst du denn? Pro Frame dein Programm neu starten?
Die Komplexität der Datenstrukturen würde doch gerade dafür sprechen sie in einem einfach wartbaren Format zu entwickeln und dann während des Build-Prozesses in etwas effizient ladbares umzuwandeln. Tausende von Arrays sind doch auch nicht der Hit. Es gibt mit Sicherheit auch die Möglichkeit der Exe im Nachhinein noch Datein einzuimpfen und vielleicht auch gleich einen Pointer darauf zu setzen. Aber ich würde diese Mühe scheuen und einfach aus einer zweiten Datei lesen. Ich würde mich auch nicht drauf verlassen das der Kernel das Binary nicht auch bloß ähnlich einem Memory Mapped File öffnet und die Seiten bei Bedarf nachlädt.
Die Komplexität der Datenstrukturen würde doch gerade dafür sprechen sie in einem einfach wartbaren Format zu entwickeln und dann während des Build-Prozesses in etwas effizient ladbares umzuwandeln. Tausende von Arrays sind doch auch nicht der Hit. Es gibt mit Sicherheit auch die Möglichkeit der Exe im Nachhinein noch Datein einzuimpfen und vielleicht auch gleich einen Pointer darauf zu setzen. Aber ich würde diese Mühe scheuen und einfach aus einer zweiten Datei lesen. Ich würde mich auch nicht drauf verlassen das der Kernel das Binary nicht auch bloß ähnlich einem Memory Mapped File öffnet und die Seiten bei Bedarf nachlädt.
- Sternmull
- Establishment
- Beiträge: 264
- Registriert: 27.04.2007, 00:30
- Echter Name: Til
- Wohnort: Dresden
Re: [C++] Array unbekannter Größe statisch initialisieren
Grad fällt mir ein das du die Daten auch während des Builds zu Quellcode formatieren könntest der sie als Array enthält. Das könnte genau so gut im Build untergebraucht werden wie die Kovertierung zu einer Binärdatei, mit dem Unterschied das man halt jedes mal die generierte Datei kompilieren und das Binary linken muss wenn sich was an den Daten geändert hat. Das wird ja z.B. gemacht um Bild-Daten einzubetten.
Edit: Oops, auch ich hatte den Beitrag von Chromanoid überlesen... da Stand genau der Vorschlag drin.
Edit: Oops, auch ich hatte den Beitrag von Chromanoid überlesen... da Stand genau der Vorschlag drin.
Zuletzt geändert von Sternmull am 20.04.2011, 22:29, insgesamt 1-mal geändert.
- Krishty
- Establishment
- Beiträge: 8350
- Registriert: 26.02.2009, 11:18
- Benutzertext: state is the enemy
- Kontaktdaten:
Re: [C++] Array unbekannter Größe statisch initialisieren
Ups, den Post hatte ich ganz übersehen, sry. Ja; ich bin eben darauf gestoßen, dass ich die Erzeugung all der Variablen per Präprozessor automatisieren könnte. Ich checke gerade, inwiefern das machbar ist.Chromanoid hat geschrieben:Schon mal über einen Code Generator, der aus Dateien in einem precompile step entsprechenden Code generiert, nachgedacht?
Und genau das ist es, wenn ich schreibe: array = { { 133, 't', "C++ ist scheiße und " }, { 0, 'x', " kommt nie an" }, … }; und mir der Compiler das dann in was reinbackt, wo es mir scheißegal sein kann, wo es landet und wie die Struktur im Detail aussieht und einfach nur array[x].y; schreiben muss.Sternmull hat geschrieben:Die Komplexität der Datenstrukturen würde doch gerade dafür sprechen sie in einem einfach wartbaren Format zu entwickeln und dann während des Build-Prozesses in etwas effizient ladbares umzuwandeln.
Doch. Und selbst, falls nicht, würde das oben immernoch zu einem lächerlichen Seitenfehler statt zu drei OS-Aufrufen kollabieren.Sternmull hat geschrieben:Ich würde mich auch nicht drauf verlassen das der Kernel das Binary nicht auch bloß ähnlich einem Memory Mapped File öffnet und die Seiten bei Bedarf nachlädt.
Diese Scheißsprache will es einfach nicht zulassen, dass ich die banalsten Dinge halbwegs ohne Nervenzusammenbruch artikulieren kann. Da kriege ich so den Hass. In C++0x würde es ja per C99-Initialisierer gehen, aber um das zu unterstützen ist sich mein Lieblings-Compiler ja zu schade.
- Chromanoid
- Moderator
- Beiträge: 4286
- Registriert: 16.10.2002, 19:39
- Echter Name: Christian Kulenkampff
- Wohnort: Lüneburg
Re: [C++] Array unbekannter Größe statisch initialisieren
Evt. in einem XML Format und die Übersetzung in Quellcode übernimmt dann ein XSLT - ich glaube das geht. Und wenn du was an der Klasse ändern willst, dann jagst du über die alte XML Datei einfach ein "Refactoring XSLT" drüber...
edit: ah mit XSL:FO und zum Beispiel http://xmlgraphics.apache.org/fop ginge textausgabe. Und bei einem Refactoring nimmst du dann einen XSLT... geht auch so mit xslt...
-
- Establishment
- Beiträge: 130
- Registriert: 01.03.2009, 14:21
- Alter Benutzername: frittentuete
Re: [C++] Array unbekannter Größe statisch initialisieren
Hi,
vielleicht habe ich einen wichtigen Schritt übersehen, aber für meine Direct3d-Vertexdeklarationen benutze ich das andauernd. :?:
Hier mal ein Auszug:
ParticleVertex.h:
ParticleVertex.cpp:
Das funktioniert. Allerdings weiß ich nicht, ob bei dir noch andere Sachen mit hineinspielen, die das verhindern könnten. :!:
vielleicht habe ich einen wichtigen Schritt übersehen, aber für meine Direct3d-Vertexdeklarationen benutze ich das andauernd. :?:
Hier mal ein Auszug:
ParticleVertex.h:
Code: Alles auswählen
typedef struct
{
...
static const D3DVERTEXELEMENT9 vert_element[];
} ParticleVertex;
Code: Alles auswählen
#include "ParticleVertex.h"
const D3DVERTEXELEMENT9 ParticleVertex::vert_element[] = {
{ 0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0 },
{ 0, 12, D3DDECLTYPE_FLOAT1, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_PSIZE, 0 },
{ 0, 16, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
{ 0, 24, D3DDECLTYPE_FLOAT1, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
{ 0, 28, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0 },
D3DDECL_END()
};
- Krishty
- Establishment
- Beiträge: 8350
- Registriert: 26.02.2009, 11:18
- Benutzertext: state is the enemy
- Kontaktdaten:
Re: [C++] Array unbekannter Größe statisch initialisieren
Dass es bei mir in einer struct liegt – das hier geht z.B. nicht:Dirk Schulz hat geschrieben:Allerdings weiß ich nicht, ob bei dir noch andere Sachen mit hineinspielen, die das verhindern könnten. :!:
Code: Alles auswählen
struct VDecl {
// D3DVERTEXELEMENT9 vert_element[]; // Fehler: Arrays unbekannter Größe dürfen keine Attribute sein. Darum:
D3DVERTEXELEMENT9 const * vert_element;
};
static VDecl const foo = {
{
{ 0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0 }, // Fehler bei der zweiten Null: Zu viele Initialisierer (der Compiler ignoriert die zweiten geschweiften Klammern und interpretiert die erste 0 nicht als Wert für das Vertex-Element, sondern für VDecl::vert_element)
…
D3DDECL_END()
}
};
// Mit C99/C++0x dürfte es gehen:
static VDecl const foo = {
.vert_element = {
{ 0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0 },
…
D3DDECL_END()
}
};
-
- Establishment
- Beiträge: 130
- Registriert: 01.03.2009, 14:21
- Alter Benutzername: frittentuete
Re: [C++] Array unbekannter Größe statisch initialisieren
Hi,
jetzt habe ich meinen Denkfehler verstanden. Das Array kann von Instanz zu Instanz verschieden sein.
Wie siehts denn mit c++0x und Variadic templates aus?
Wäre vielleicht eine Alternative, habe mich damit aber noch nicht befasst, deswegen weiß ich nicht, ob intern nicht auch Zwischenvariablen benutzt werden.
jetzt habe ich meinen Denkfehler verstanden. Das Array kann von Instanz zu Instanz verschieden sein.
Wie siehts denn mit c++0x und Variadic templates aus?
Wäre vielleicht eine Alternative, habe mich damit aber noch nicht befasst, deswegen weiß ich nicht, ob intern nicht auch Zwischenvariablen benutzt werden.
Re: [C++] Array unbekannter Größe statisch initialisieren
Wie wär's wenn du eine maximale Größe des Arrays festlegst und die nicht benötigten Elemente selber nullst?
Ist natürlich u.U. etwas verschwenderisch, aber einfach.
Ist natürlich u.U. etwas verschwenderisch, aber einfach.
- Krishty
- Establishment
- Beiträge: 8350
- Registriert: 26.02.2009, 11:18
- Benutzertext: state is the enemy
- Kontaktdaten:
Re: [C++] Array unbekannter Größe statisch initialisieren
Wenn mir C++0x uir Verfüging stünde, kömnte ich auch gleich die C99.Syntax benutzenDirk Schulz hat geschrieben:Wie siehts denn mit c++0x und Variadic templates aus?
Ja, habe ich auchj schon dürber nachgedachtHelmut hat geschrieben:Wie wär's wenn du eine maximale Größe des Arrays festlegst und die nicht benötigten Elemente selber nullst?
Ist natürlich u.U. etwas verschwenderisch, aber einfach.
Aber bei 1000 Array-Elemenenbten, die imSchnitt eine Größe von 3 und maxima eine Größe von 10 haben wären >50 % verschwendet
Bääääh
Ihc glaube, ich mache das jezt mit #defines
Das ist der einzgie Grund, wofür man dne bekackten Präprozessor noch benutzen kann
Umd die schwächen der Sprache auszugleichen
Hass
Ehrlich, ich habe die Schnauze sowas von gehstrichen voll von der ganzen Scheiße (nicht nmur C++ sondern generell)
- Aramis
- Moderator
- Beiträge: 1458
- Registriert: 25.02.2009, 19:50
- Echter Name: Alexander Gessler
- Wohnort: 2016
- Kontaktdaten:
Re: [C++] Array unbekannter Größe statisch initialisieren
Haettest du halt vorher nicht jedes Byte an Platz muehsam rausgepfriemelt - dann wuerden dir die paar verschwendeten Bytes jetzt nicht das Herz brechen :-)
- Krishty
- Establishment
- Beiträge: 8350
- Registriert: 26.02.2009, 11:18
- Benutzertext: state is the enemy
- Kontaktdaten:
Re: [C++] Array unbekannter Größe statisch initialisieren
Wäre ich halt statt mühsam zu programmieren dabei geblieben, mich über anderer Leute Prinzipien lustig zu machen