PPCNUX / mcnix

Diskussionen rund um Linux, PowerPC und Apple
Aktuelle Zeit: Sa 25 Mai 2013, 04:28:00

Alle Zeiten sind UTC + 1 Stunde [ Sommerzeit ]




Ein neues Thema erstellen Auf das Thema antworten  [ 11 Beiträge ] 
Autor Nachricht
 Betreff des Beitrags: Initialisierung von Arrays
BeitragVerfasst: Mo 20 Oktober 2003, 17:49:53 
Offline
PPCNUX Team
Benutzeravatar

Registriert: Di 09 Juli 2002, 16:57:13
Beiträge: 501
Wohnort: Tal der Ahnungslosen
Sollten laut "Standard" (wenn es den gibt) Felder unter C++ nicht grundsätzlich mit '0' initialisiert werden?

Habe näml. folgendes:
Code:
#define MAX 20
char **p;
p = new char * [MAX];

int i = 0;
while(*(p+i))
{
  //...
}

Da müsste er doch gleich am ersten Element aus der Schleife springen. Scheinbar tut er es aber unter Windows (.NET) nicht (leider hier Referenzplattform) nicht, denn lasse ich mir i dann ausgeben, kommt die 21 *grr*. der g++ unter Mac OS X/Linux macht da keine Probs... (ok, man kann das Feld ja manuell in 'ner Schleife mit 0 initialisieren, aber so'n Fehler zu finden kostet Nerven...)

Lars


Nach oben
 Profil  
 
 Betreff des Beitrags:
BeitragVerfasst: Mo 20 Oktober 2003, 18:45:32 
Offline
PPCNUX Team
Benutzeravatar

Registriert: So 08 September 2002, 15:12:03
Beiträge: 1280
Wohnort:
AFAIK gibt es bei C++ keine definierte Initialisierung von Variablen oder Arrays, also weder 0 noch iregndeinanderer Wert, es sei den es existiert ein Konstruktor für den Typ.

Ich initialisere daher meine Arrays immer selbst mit
[code[
void *memset(void *s, int c, size_t n);
[/code]
Damit werden 'n' Bytes ab 's' mit dem Wert 'c' (genaugenommen mit den unteren 8 bit)
beschrieben. Das ist schneller als jede Schleife, da in der libc opptimal implementiert.

Ich weiss aber nciht ob diese Funktion auch unter .NET zur Verfügung steht.

Bis dann

R"udiger


Nach oben
 Profil  
 
 Betreff des Beitrags:
BeitragVerfasst: Mo 20 Oktober 2003, 19:22:03 
Offline
PPCNUX Team
Benutzeravatar

Registriert: Di 09 Juli 2002, 16:57:13
Beiträge: 501
Wohnort: Tal der Ahnungslosen
Hmm, zumindest steht in Stroustrups Büchern für folgenden Fall:

Code:
int v[5] = {1,2,3}


dass die restl. beiden Elemente mit 0 belegt werden müssten, aber evtl. gilt das nicht, weil es sich ja um ein Feld aus Zeiger auf char * handelt (or it's just a bug - who knows).

memset() gibt es aber auch bei Visual C++ (.NET habe ich Moment nicht).

Lars


Nach oben
 Profil  
 
 Betreff des Beitrags:
BeitragVerfasst: Mo 20 Oktober 2003, 20:49:05 
Offline
PPCNUX Team
Benutzeravatar

Registriert: So 08 September 2002, 15:12:03
Beiträge: 1280
Wohnort:
Hallo,

Wenn ich eines gelernt habe, dann folgendes:

Initialisiere immer selbst!

Vor allem, da der gcc bei höheren Optimierungsstufen gerne mal die Initialisierung wieder
weglässt. Und gcc unter x86 verhält sich wieder anders als unter ppc. Ergo tus selber.

Bis dann

R"udiger


Nach oben
 Profil  
 
 Betreff des Beitrags: Re: Initialisierung von Arrays
BeitragVerfasst: Di 21 Oktober 2003, 09:07:41 
Offline

Registriert: Do 31 Oktober 2002, 11:09:58
Beiträge: 212
larsi hat geschrieben:
Sollten laut "Standard" (wenn es den gibt) Felder unter C++ nicht grundsätzlich mit '0' initialisiert werden?

Habe näml. folgendes:
Code:
#define MAX 20
char **p;
p = new char * [MAX];

int i = 0;
while(*(p+i))
{
  //...
}



Erst einmal ein paar Worte zu Deinem Programmstil
Code:
const size_t MAX = 20;
char** p = new char* [MAX];

for (size_t i = 0; *(p+i);) {
    // code
}


Man benutzt define nur dann, wenn es gar nicht anders geht, sprich includes und includes guards und sonst nie! Selbst bedingte Compilierung sollte man wann immer möglich vermeiden. Templates sind für diesen Zweck besser geeignet.

Die zero initialization gilt nur Objekte die normal angelegt wurden, Speicher der via Allokatoren (new, new[], malloc, ...) angefordert wurde ist in irgend einem Zustand, sprich undefined.


Nach oben
 Profil  
 
 Betreff des Beitrags: Re: Initialisierung von Arrays
BeitragVerfasst: Di 21 Oktober 2003, 09:19:01 
Offline
PPCNUX Team
Benutzeravatar

Registriert: So 08 September 2002, 15:12:03
Beiträge: 1280
Wohnort:
tjp hat geschrieben:

Man benutzt define nur dann, wenn es gar nicht anders geht, sprich includes und includes guards und sonst nie! Selbst bedingte Compilierung sollte man wann immer möglich vermeiden.


Warum? Hast du ne Begründung zur Hand? Ich bennutze Macros ("defuines") gerne um z.B.
Debug-Code zur Compile-Zeit ein- und auszuschlaten. Und was ist der Vorteil von
const int gegenüber #define?

tjp hat geschrieben:
Templates sind für diesen Zweck besser geeignet.

Die zero initialization gilt nur Objekte die normal angelegt wurden, Speicher der via Allokatoren (new, new[], malloc, ...) angefordert wurde ist in irgend einem Zustand, sprich undefined.


Wenn wenigstens dann immer garbage drin stände. Leider ist es jedoch so, dass solche Specihersegemente oft doch auf 0 initialisiert sind (abhängig auch von der Optimierstufe und der Hardwarepalttform). Daher passiert es mir beim rapid prototyping viel zu oft, dass ein Code ohne explizite Initialisierung funktioniert, aber bei höheren Optimierungen oder anderen Hardware-Plattformen streikt. Und dann geht die Suche los.

Bis dann

R"udiger


Nach oben
 Profil  
 
 Betreff des Beitrags: Re: Initialisierung von Arrays
BeitragVerfasst: Di 21 Oktober 2003, 10:38:04 
Offline

Registriert: Do 31 Oktober 2002, 11:09:58
Beiträge: 212
goetz hat geschrieben:
Warum? Hast du ne Begründung zur Hand? Ich bennutze Macros ("defuines") gerne um z.B.
Debug-Code zur Compile-Zeit ein- und auszuschlaten. Und was ist der Vorteil von
const int gegenüber #define?


Dann compiliere larsi Beispiel mal mit
Code:
g++ -DMAX=-1 ...

Man kann defines von außen beliebig überschreiben, und defines sind nicht typesafe. Das ist bloß Makroexpansion, Du kannst Dir nie sicher sein, daß ein include Deine defines nicht kaputt macht oder ein Compilerflag sie überschreibt.

Pragmas und bedingte Compilierung stehen so irgend wo dazwischen. Wenn möglich sollte man auch auf sie verzichten. Durch geeignetes Design der Klassen kann man das Problem auch erschlagen.

Die Debugausgabe kann man via Policyclasses ermöglichen, dann muß man in z.B. einer config.h nur passende Typedefs reinschreiben, um das Debugging ein- und auszuschalten. Der Compiler optimiert dann die Aufrufe fürs Debugging weg. und der Programmcode wird deutlich sauberer, da das Debugging in einer eigenen Policyclass ausgelagert ist und nicht der eigentliche Programmcode mit ifdef else endif verseucht ist.

Der Meister hätte am liebsten cpp in den Müll entsorgt. Siehe The Design and Evolution of C++, Bjarne Stroustrup.


Nach oben
 Profil  
 
 Betreff des Beitrags: Re: Initialisierung von Arrays
BeitragVerfasst: Di 21 Oktober 2003, 10:56:51 
Offline
PPCNUX Team
Benutzeravatar

Registriert: So 08 September 2002, 15:12:03
Beiträge: 1280
Wohnort:
tjp hat geschrieben:
goetz hat geschrieben:
Warum? Hast du ne Begründung zur Hand? Ich bennutze Macros ("defuines") gerne um z.B.
Debug-Code zur Compile-Zeit ein- und auszuschlaten. Und was ist der Vorteil von
const int gegenüber #define?


Dann compiliere larsi Beispiel mal mit
Code:
g++ -DMAX=-1 ...


Man kann defines von außen beliebig überschreiben, und defines sind nicht typesafe. Das ist bloß Makroexpansion, Du kannst Dir nie sicher sein, daß ein include Deine defines nicht kaputt macht oder ein Compilerflag sie überschreibt.


O.K. Solange man aber als einiger an den Progs arbeitet dürfte sich das Problem in Grenzen halten. Bliebe noch die Frage zu klären, ob bei automatischen Variablen in Funktionen/Methoden der Art
[code[
int var[MAX1 + MAX2*LINES2];
[/code]
der Compiler es in beiden Fällen zur Compilezeit auflöst. Entsprechend, ob der Compiler bei bei const-Variablen einen extra Speicherzugriff hat oder nicht (variable wird aus Speicher geladen, Macro-Konstante steht explizit im Prog-Code. Bei oft Aufgerufenen Funktionen kann das schon mal ein paar % Performance machen/

Zitat:
Pragmas und bedingte Compilierung stehen so irgend wo dazwischen. Wenn möglich sollte man auch auf sie verzichten. Durch geeignetes Design der Klassen kann man das Problem auch erschlagen.

Die Debugausgabe kann man via Policyclasses ermöglichen, dann muß man in z.B. einer config.h nur passende Typedefs reinschreiben, um das Debugging ein- und auszuschalten. Der Compiler optimiert dann die Aufrufe fürs Debugging weg. und der Programmcode wird deutlich sauberer, da das Debugging in einer eigenen Policyclass ausgelagert ist und nicht der eigentliche Programmcode mit ifdef else endif verseucht ist.


Sicher es ist unschön. Und gerne mach ich es auch nicht. Aber wenn ich bei einer rekursiven Funktion jedes if darin checkn muss, seh ich kaum eine andere Möglichkeit als jedes mit einem else zu versehen, dass ich aber im fertigen Code nicht mehr drin haben möchte. Wie ich da mit einer zweiten Klasse ran soll ist mir unklar. Es sei den ich dupliziere die die Klasse eine mit und eine ohne Debug-Code. Dann hab ich aber das Problem,sicher gehen zu müssen, dass alle Änderungen während des Debuggings aus der Debug-Klasse zurück in des "normale" Klasse fliessen.

Bis dann

R"udiger

PS: Ich lerne immer gen dazu, wobi ich nach wie vor noch von C herkomme und recht stark prozedual denke.


Nach oben
 Profil  
 
 Betreff des Beitrags: Re: Initialisierung von Arrays
BeitragVerfasst: Di 21 Oktober 2003, 18:16:29 
Offline

Registriert: Do 31 Oktober 2002, 11:09:58
Beiträge: 212
goetz hat geschrieben:

O.K. Solange man aber als einiger an den Progs arbeitet dürfte sich das Problem in Grenzen halten. Bliebe noch die Frage zu klären, ob bei automatischen Variablen in Funktionen/Methoden der Art
Code:
int var[MAX1 + MAX2*LINES2];

der Compiler es in beiden Fällen zur Compilezeit auflöst. Entsprechend, ob der Compiler bei bei const-Variablen einen extra Speicherzugriff hat oder nicht (variable wird aus Speicher geladen, Macro-Konstante steht explizit im Prog-Code. Bei oft Aufgerufenen Funktionen kann das schon mal ein paar % Performance machen/


Ein guter Compiler sollte das optimieren können, da er weiß, daß MAX konstant ist.

goetz hat geschrieben:

Sicher es ist unschön. Und gerne mach ich es auch nicht. Aber wenn ich bei einer rekursiven Funktion jedes if darin checkn muss, seh ich kaum eine andere Möglichkeit als jedes mit einem else zu versehen, dass ich aber im fertigen Code nicht mehr drin haben möchte. Wie ich da mit einer zweiten Klasse ran soll ist mir unklar. Es sei den ich dupliziere die die Klasse eine mit und eine ohne Debug-Code. Dann hab ich aber das Problem,sicher gehen zu müssen, dass alle Änderungen während des Debuggings aus der Debug-Klasse zurück in des "normale" Klasse fliessen.

Bis dann

R"udiger

PS: Ich lerne immer gen dazu, wobi ich nach wie vor noch von C herkomme und recht stark prozedual denke.



Der Gedanke ist es Metaprogramming zumachen.

class Debug {
debugcode();
};

class NoDebug {
debugcode () {};
};

template <typename DebugPolicy = NoDebug>
class Demo {
// normale Klassendefinition
};

typedef Demo<NoDebug> MyDemoType;
bzw.
typedef Demo>Debug> MyDemoType;

kannst Du dann das Debugging an- und ausschalten. In diesem Falle ist debugcode eine Methode die von Demo aufgerufen wird. Wenn man sie leer definiert, wird sie üblicherweise wegoptimiert.

Richtig gut wird das ganze in C++ Templates, Vandervoorde, Josuttis erklärt. Anwendungen von Policy Klassen kann man unter anderem in Modern C++, Alexandrescu finden, beide Bücher von Addison-Wesley/Pearson Education.


Nach oben
 Profil  
 
 Betreff des Beitrags:
BeitragVerfasst: Di 21 Oktober 2003, 18:44:08 
Offline
PPCNUX Team
Benutzeravatar

Registriert: So 08 September 2002, 15:12:03
Beiträge: 1280
Wohnort:
Hallo,

Ich seh noch nicht wie mir das hilft, da der debug-Code in meinem Fall in der Methode steht, die ich debuggen will (im debugging-Fall möchte ich wissen, wann er eine Rekursion abbricht und welche Bedingung dazu geführt hat abzubrechen, bzw. warum er weiter in der Rekursion runtergeht, obwohl er es nicht sollte).

Aber wir müssen das jetzt auch nciht unbedingt vertiefen. Ich komm bisher auch so zurecht ;-)

Bis dann

R"udiger


Nach oben
 Profil  
 
 Betreff des Beitrags:
BeitragVerfasst: Di 21 Oktober 2003, 20:35:49 
Offline

Registriert: Do 31 Oktober 2002, 11:09:58
Beiträge: 212
goetz hat geschrieben:
Aber wir müssen das jetzt auch nciht unbedingt vertiefen. Ich komm bisher auch so zurecht ;-)

Hallo

Man muß halt die Klassen entsprechend designen. Nachträglich das ganze einzubauen wird schwierig. Außer man will Fowlers Buch von vorne bis hinten in der Praxis "erproben". ;-)

Gruß


Nach oben
 Profil  
 
Beiträge der letzten Zeit anzeigen:  Sortiere nach  
Ein neues Thema erstellen Auf das Thema antworten  [ 11 Beiträge ] 

Alle Zeiten sind UTC + 1 Stunde [ Sommerzeit ]


Wer ist online?

Mitglieder in diesem Forum: Keine Mitglieder und 1 Gast


Du darfst keine neuen Themen in diesem Forum erstellen
Du darfst keine Antworten zu Themen in diesem Forum erstellen
Du darfst deine Beiträge in diesem Forum nicht ändern
Du darfst deine Beiträge in diesem Forum nicht löschen
Du darfst keine Dateianhänge in diesem Forum erstellen

Suche nach:
Gehe zu:  
cron
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group. Color scheme by ColorizeIt.
Deutsche Übersetzung durch phpBB.de