(gelöst)[C++]Array-Größe statisch kontrollieren

Programmiersprachen, APIs, Bibliotheken, Open Source Engines, Debugging, Quellcode Fehler und alles was mit praktischer Programmierung zu tun hat.
Antworten
Benutzeravatar
Krishty
Establishment
Beiträge: 8350
Registriert: 26.02.2009, 11:18
Benutzertext: state is the enemy
Kontaktdaten:

(gelöst)[C++]Array-Größe statisch kontrollieren

Beitrag von Krishty »

Hi,

Ich habe in einem Header:
extern int const array[123];
Und in einer anderen Datei:
int const array[] = { 1, 2, 3, ..., 123 };

Gibt es irgendeine Möglichkeit, dass mich der Compiler warnt, wenn ich die Array-Größe in der Deklaration ändere, aber die Definition unterschiedlich viele Initialisierungswerte zur Verfügung stellt? Atm füllt er Überschuss einfach alles mit 0 auf und das ist fail auf ganzer Linie.

Einen K'tor selber zu definieren ist keine Möglichkeit, da ich das Array statisch benötige.

Gruß, Ky
Zuletzt geändert von Krishty am 22.04.2011, 17:02, insgesamt 2-mal geändert.
seziert Ace Combat, Driver, und S.T.A.L.K.E.R.   —   rendert Sterne
Benutzeravatar
Sternmull
Establishment
Beiträge: 264
Registriert: 27.04.2007, 00:30
Echter Name: Til
Wohnort: Dresden

Re: [C++]Array-Größe statisch kontrollieren

Beitrag von Sternmull »

Das auffüllen mit Nullen ist standardgerechtes Verhalten. Ein Lösungsvorschlag:

Code: Alles auswählen

// im Header:
enum
{
    MyArrayLen = 3,
};

template <class T>
class Initialized
{
   Initialized(); // Default ctor verbieten
public:

   T const val;

   Initialized(T val) : val(val)
   {}

   operator T () const
   {
      return val;
   }
};

typedef Initialized<int> InitializedInt;


extern InitializedInt const myArray[MyArrayLen];


// irgendwo anders:

InitializedInt const myArray[MyArrayLen] = {1, 2}; // Tadaa: error: calling a private constructor of class 'Initialized<int>'
Also die Werte in eine Klasse kapseln die keinen öffentlichen Default-Konstruktor hat und die Länge des Arrays auch bei der Initialisierung explizit angeben. Nun meckert der Compiler wenn nicht die richtige Anzahl initialisiert wird. Wenn es zu wenige sind fehlt ihm der Zugriff auf den Default-Konstruktor um die restlichen Elemente implizit zu initialisieren. Wenn es zu viele sind meckert er grundsätzlich.
Benutzeravatar
Krishty
Establishment
Beiträge: 8350
Registriert: 26.02.2009, 11:18
Benutzertext: state is the enemy
Kontaktdaten:

Re: [C++]Array-Größe statisch kontrollieren

Beitrag von Krishty »

Gewieft, aber es scheitert an der unendlichen Scheißigkeit des Compilers.

Was wir beide wollen, ist:
  • Im read-only-Datensegment der Exe werden, sagen wir, 4 KiB für 1000 Array-Elemente allokiert
  • Da kompiliert er die Werte rein
  • ???
  • PROFIT
Was dein Vorschlag bewirkt ist:
  • Im read-write-Datenabschnitt der Exe werden 4 KiB allokiert
  • Ein statischer Initialisierer für das Array wird eingetragen
  • Der Compiler produziert eine Extrafunktion, die das Array initialisiert (hier stand vorher die Assembly, aber das ist eine andere Sache)
  • Wenn die Exe gestartet wird, wird neben den anderen statischen K’toren auch diese Funktion aufgerufen und verbringt erstmal eine ganze Weile damit, das Array in den read-write-Datenabschnitt zu schreiben
  • ???
  • Längere Initialisierungszeit, größere Exe, fail
Danke für den Versuch, aber es hat schon einen Grund, dass ich sage: K’toren sind keine Lösung. Übrigens der perfekte Gegenbeweis für alle, die sagen, mit C++ sei maschinennah. Was der C++-Compiler hier für vollkommen trivialen Text auf höchster Optimierungsstufe ausspuckt, das ist bestenfalls nativ kompiliertes Java.
seziert Ace Combat, Driver, und S.T.A.L.K.E.R.   —   rendert Sterne
Benutzeravatar
Krishty
Establishment
Beiträge: 8350
Registriert: 26.02.2009, 11:18
Benutzertext: state is the enemy
Kontaktdaten:

Re: [C++]Array-Größe statisch kontrollieren

Beitrag von Krishty »

Ich teste nun – in #ifdef _DEBUG gewrappt – die Array-Größe gegen die hardgecodete letzte bekannte Array-Größe. Stimmen die beiden nicht überein – wurde die Array-Deklaration also seit der letzten Kompilierung verändert – werden alle Werte durchgegangen und getestet, ob sie komplett 0 sind. (Das kann ich mir überhaupt erst erlauben, weil ich ein paar Attribute habe, bei denen 0 kein gültiger Zustand ist.) Danach fordert eine hochgehende Assertion auf, die hardgecodete Array-Größe anzupassen.

Ich habe nun also einen Sollbruchdurchlauf, wenn ich die Array-Ausmaße anpasse. Nicht die feine englische Art, aber ich fühle mich zu sehr dieser stumpfsinnigen Scheiße überlegen, um noch mehr zu investieren. Trotzdem danke für die Hilfe, Sternmull.
seziert Ace Combat, Driver, und S.T.A.L.K.E.R.   —   rendert Sterne
Benutzeravatar
Krishty
Establishment
Beiträge: 8350
Registriert: 26.02.2009, 11:18
Benutzertext: state is the enemy
Kontaktdaten:

Re: (gelöst)[C++]Array-Größe statisch kontrollieren

Beitrag von Krishty »

ARGH es ist so einfach: Man verbirgt das Array einfach vor dem Rest, damit man Deklaration und Definition überhaupt nicht mehr trennen muss.

Anstatt also ein globales Array zu deklarieren, deklariert man eine globale Funktion, die einen Index erwartet und eine Referenz zum entsprechenden Element zurückgibt. Die definiert man in irgendeiner einsamen nicht-Header-Datei, packt die Array-Definition mit automatischer Größe (array[] = {) drüber or rein und ein static_assert() gegen die erwartete Größe dahinter.

Eine Nebenwirkung ist, dass man dann auch zentral auf out-of-Bounds-Zugriffe testen kann.
seziert Ace Combat, Driver, und S.T.A.L.K.E.R.   —   rendert Sterne
Antworten