Hypercell ein ] Hypercell aus ] Zeige Navigation ] Verstecke Navigation ]
c++.de  
   
Forentreff 2012     
Bücher-Shop mit Amazon (Buchkategorien)C++ : Referenzen zu C++ : C++ Builder : Visual C++ : C# : Java : Spieleprogrammierung : Systemprogrammierung Linux : Software-Entwicklung : .NET : Compilertechnik : Algorithmen & Datenstrukturen : Objektorientierung : Entwurfsmuster : UML : eXtreme Programming : Scrum : Projektmanagement : Software-Testing : Datenbanken : Tom DeMarco : Dilbert : User Friendly
C/C++ Forum :: Allgemeines zum Magazin ::  [Suchen Autor für:] Bugs bei denen man lange sitzt     Zeige alle Beiträge auf einer Seite Auf Beitrag antworten
Autor Nachricht
Ben04
Autor

Benutzerprofil
Anmeldungsdatum: 10.10.2004
Beiträge: 1635
Beitrag Ben04 Autor 23:17:38 09.06.2007   Titel:   [Suchen Autor für:] Bugs bei denen man lange sitzt            Zitieren

Wie wäre es mit einem Artikel bezüglich eher ungewöhnlichen Bugs bei denen man lange sitzt ehe man sie gefunden hat. Also so eine Art Auflistung.

Ich hätte vier Kandidaten:

  • Selbstinitialisierung
    C/C++ Code:
    class Car{
    public:
      Car(const std::string&brant_name):
        brand_name(brand_name){}
    private:
      std::string brand_name;
    };
    C/C++ Code:
    class Car{
    public:
    Car(const std::string&brant_name):
    brand_name(brand_name){}
    private:
    std::string brand_name;
    };
    C/C++ Code:
    class Car{
    public:
      Car(const std::string&brant_name):
        brand_name(brand_name){}
    private:
      std::string brand_name;
    };

  • Parameter deckt Member
    C/C++ Code:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    1
    2
    3
    4
    5
    6
    7
    8
    9
    class Car{
    public:
      Car(std::string brand_name):
        brand_name("Audi"){
        brand_name = "VW";
      }
    private:
      std::string brand_name;
    };
    C/C++ Code:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    class Car{
    public:
    Car(std::string brand_name):
    brand_name("Audi"){
    brand_name = "VW";
    }
    private:
    std::string brand_name;
    };
    C/C++ Code:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    class Car{
    public:
      Car(std::string brand_name):
        brand_name("Audi"){
        brand_name = "VW";
      }
    private:
      std::string brand_name;
    };

  • Ändern der Interna der Basisklasse bricht abgeleitete Klasse

    Dies funktioniert
    C/C++ Code:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    int foo;

    class Base{
    private:
      int bar;
    };

    class Derived:public Base{
    public:
      void my_func(){
        foo = 4;
      }
    };
    C/C++ Code:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    int foo;

    class Base{
    private:
    int bar;
    };

    class Derived:public Base{
    public:
    void my_func(){
    foo = 4;
    }
    };
    C/C++ Code:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    int foo;

    class Base{
    private:
      int bar;
    };

    class Derived:public Base{
    public:
      void my_func(){
        foo = 4;
      }
    };

    So nun wird Base geändert und es geht nicht mehr:
    C/C++ Code:
    class Base{
    private:
      int foo;
    };
    C/C++ Code:
    class Base{
    private:
    int foo;
    };
    C/C++ Code:
    class Base{
    private:
      int foo;
    };

    (Ist kein Compiler-Bug sondern ein Standard-Bug)
  • Unterschied foo, this->foo in Templateklassen
    http://www.parashift.com/c++-faq-lite/templates.html#faq-35.19


Wer noch Kandidaten hat kann sie ja einfach mal nennen. Vielleicht macht ja irgendwer mal ein Artikel draus.


Zuletzt bearbeitet von estartu am 14:34:56 14.01.2008, insgesamt 2-mal bearbeitet
estartu
Moderator

Benutzerprofil
Anmeldungsdatum: 05.09.2003
Beiträge: 11494
Beitrag estartu Moderator 13:24:32 13.06.2007   Titel:              Zitieren

Sieht nett aus. :)

_________________
Das c-plusplus.de-Magazin sucht Mitmacher --- Die Artikel --- meine Homepage
chrische5
Mitglied

Benutzerprofil
Anmeldungsdatum: 23.05.2005
Beiträge: 5014
Beitrag chrische5 Mitglied 16:59:06 13.06.2007   Titel:              Zitieren

Hallo

Reihenfolge in der Initialisierungsliste ist auch ein guter Kanidat.

chrische

_________________
"Mach mal einem Bekloppten klar, dass er bekloppt ist." Dieter Bohlen
LordJaxom
Mitglied

Benutzerprofil
Anmeldungsdatum: 23.11.2005
Beiträge: 5550
Beitrag LordJaxom Mitglied 17:11:59 13.06.2007   Titel:              Zitieren

Off-by-one Fehler, die sich erst viel später auswirken. Folgendes Beispiel hatte ich sinngemäß erst vorgestern, wobei die Funktion "func" nicht von mir war und nur compiliert vorlag :(. Habs dann über nen Watchpoint gefunden. (Ist aber ANSIC).

C/C++ Code:
1
2
3
4
5
6
7
8
9
10
11
12
1
2
3
4
5
6
7
8
9
10
11
12
void func( char* buffer, size_t length ) {
    buffer[ length ] = '\0';
    strcpy( somewhere, buffer );
}

void use() {
    char buffer[ 2000 ];
    char hostname[ 256 ];

    strcpy( hostname, "My_Pc" );
    func( buffer, sizeof( buffer ) ); // wenn die stack-ausrichtung stimmt ist hostname jetzt leer
}
C/C++ Code:
1
2
3
4
5
6
7
8
9
10
11
12
void func( char* buffer, size_t length ) {
buffer[ length ] = '\0';
strcpy( somewhere, buffer );
}

void use() {
char buffer[ 2000 ];
char hostname[ 256 ];

strcpy( hostname, "My_Pc" );
func( buffer, sizeof( buffer ) ); // wenn die stack-ausrichtung stimmt ist hostname jetzt leer
}
C/C++ Code:
1
2
3
4
5
6
7
8
9
10
11
12
void func( char* buffer, size_t length ) {
    buffer[ length ] = '\0';
    strcpy( somewhere, buffer );
}

void use() {
    char buffer[ 2000 ];
    char hostname[ 256 ];

    strcpy( hostname, "My_Pc" );
    func( buffer, sizeof( buffer ) ); // wenn die stack-ausrichtung stimmt ist hostname jetzt leer
}


Zuletzt bearbeitet von LordJaxom am 17:12:35 13.06.2007, insgesamt 1-mal bearbeitet
rüdiger
Moderator

Benutzerprofil
Anmeldungsdatum: 11.07.2001
Beiträge: 22819
Beitrag rüdiger Moderator 03:06:35 14.06.2007   Titel:   Re: [Vorschlag] Bugs bei denen man lange sitzt            Zitieren

Ben04 schrieb:


  • Selbstinitialisierung
    C/C++ Code:
    class Car{
    public:
      Car(const std::string&brant_name):
        brand_name(brand_name){}
    private:
      std::string brand_name;
    };
    C/C++ Code:
    class Car{
    public:
    Car(const std::string&brant_name):
    brand_name(brand_name){}
    private:
    std::string brand_name;
    };
    C/C++ Code:
    class Car{
    public:
      Car(const std::string&brant_name):
        brand_name(brand_name){}
    private:
      std::string brand_name;
    };



Wo ist das Problem?

Aber im Grunde glaube ich nicht das man daraus einen guten Artikel schreiben kann und vor dem meisten warnen die Compiler ja, wenn es nicht sogar einen Fehler generiert.

_________________
.
Jester
Moderator

Benutzerprofil
Anmeldungsdatum: 06.04.2001
Beiträge: 8331
Beitrag Jester Moderator 09:35:47 14.06.2007   Titel:              Zitieren

Ich denke schon, dass man da insgesamt was nettes schreiben kann. Allerdings denke ich nicht, dass es genügt eine Liste von Bugs zu machen und zu sagen: "Boah, die waren alle soo schwer zu finden."

Wie bereits eindrucksvoll bestätigt (ich wollte gestern schon antworten, dachte aber ich warte noch bis sich jemand meldet, danke ;)) wird es immer einen geben, der so einen Bug anschaut und sagt: "Öh, der is doch voll einfach zu finden. Ist ja garkein Problem."

Vielmehr sollten in so einen Artikel dann auch Tipps/Tricks und Techniken rein, die helfen genau diese Fehler zu finden oder gleich zu vermeiden. Vieles davon kann man sehr leicht über Unit-Tests rausfinden. Bei anderen Sachen hilft vielleicht eine klare Namenskonvention. Wer beispielsweise wie ich Parameter und Member nicht gleich benennt, dem kann manches davon garnicht passieren etc.

_________________
Mod im Mathe-Forum

Die dümmsten Programmierer schreiben die dicksten Programme.
Artchi
Autor

Benutzerprofil
Anmeldungsdatum: 16.03.2002
Beiträge: 8576
Beitrag Artchi Autor 10:30:19 14.06.2007   Titel:              Zitieren

Kann überhaupt ein einziger Autor solch eine Liste aufschreiben? Man, der muß ja echt Probleme gehabt haben. :D ;)

Wenn dann kann man doch nur sowas sammeln. Was ja hier in diesem Thread passiert. Und ich will mich mal anschliessen.

Ich hatte mal ein switch-case-Konstrukt. nichts spektakuläres:

C/C++ Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
1
2
3
4
5
6
7
8
9
10
11
12
13
14
switch(a)
{
   case right:
        rechts();
        break;
   case left:
        links();
        break;
   case down:
        runter();
   case up:
        hoch();
        break;
}
C/C++ Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
switch(a)
{
case right:
rechts();
break;
case left:
links();
break;
case down:
runter();
case up:
hoch();
break;
}
C/C++ Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
switch(a)
{
   case right:
        rechts();
        break;
   case left:
        links();
        break;
   case down:
        runter();
   case up:
        hoch();
        break;
}

Tja, und ich habe ewig gesucht, woran das Problem liegen könnte. Nur nicht im switch-case-Konstrukt! Weil ich den Fehler erst später bemerkt habe, kam ich nicht auf die Idee dort zu suchen.

Was habe ich daraus gelernt? zu jedem case überprüfe ich heute instinktiv ob ich auch ein passendes break habe. Sobald ich case schreibe, hau ich sofort ein break rein. Egal was kommt! Das break kann ich immer noch weg nehmen, wenn ich es doch nicht brauche.

_________________
Bring back the Windows Start Menu Petition | GoPetition


Zuletzt bearbeitet von Artchi am 10:32:16 14.06.2007, insgesamt 1-mal bearbeitet
Jester
Moderator

Benutzerprofil
Anmeldungsdatum: 06.04.2001
Beiträge: 8331
Beitrag Jester Moderator 10:50:23 14.06.2007   Titel:              Zitieren

Artchi schrieb:
Was habe ich daraus gelernt? zu jedem case überprüfe ich heute instinktiv ob ich auch ein passendes break habe. Sobald ich case schreibe, hau ich sofort ein break rein. Egal was kommt!


Genau das meine ich, sowas gehört in sonen Text auf jeden Fall mit rein.

Zitat:
Das break kann ich immer noch weg nehmen, wenn ich es doch nicht brauche.


Und dann hoffentlich nen Kommentar, damit's bei der nächsten Fehlersuche nicht von jemand anders blind reingesetzt wird "klar, dass das nicht tut, da fehlt ja 'n break".

_________________
Mod im Mathe-Forum

Die dümmsten Programmierer schreiben die dicksten Programme.
pale dog
Mitglied

Benutzerprofil
Anmeldungsdatum: 27.04.2007
Beiträge: 1258
Beitrag pale dog Mitglied 10:54:41 14.06.2007   Titel:              Zitieren

Artchi schrieb:

Tja, und ich habe ewig gesucht, woran das Problem liegen könnte. Nur nicht im switch-case-Konstrukt!

single-step im debugger, dann hätteste es leicht gefunden ;)

Artchi schrieb:

Was habe ich daraus gelernt? zu jedem case überprüfe ich heute instinktiv ob ich auch ein passendes break habe. Sobald ich case schreibe, hau ich sofort ein break rein. Egal was kommt! Das break kann ich immer noch weg nehmen, wenn ich es doch nicht brauche.

ich würde aber noch einen kommentar hinschreiben,
mindestens: /* Intentionally no BREAK here */
sonst baut man später noch ein break ein, weil man meint es vergessen zu haben. :D
edit: zu laaahhhhm :(

topic: am schlimmsten finde ich bugs, die man nicht selber fabriziert hat, z.b. falsch funktionierende library-funktionen und dergleichen...
:)

_________________
http://users.aol.com/s6sj7gt/mike666.htm


Zuletzt bearbeitet von pale dog am 10:55:35 14.06.2007, insgesamt 1-mal bearbeitet
estartu
Moderator

Benutzerprofil
Anmeldungsdatum: 05.09.2003
Beiträge: 11494
Beitrag estartu Moderator 13:15:11 14.06.2007   Titel:              Zitieren

Ich werde immer mal wiede rausgelacht, weil ich IMMER Klammern setze.
Ich habe grundsätzlich zu viele Klammern... egal ob () oder {}

Allerdings ist mir sowas lieber als die Sucherei, warum das immer Meldung macht und nicht nur, wenn x, was es soll:
C/C++ Code:
if (x == 3)
    tuwas();
    MachMeldung();
tuwasanderes();
C/C++ Code:
if (x == 3)
tuwas();
MachMeldung();
tuwasanderes();
C/C++ Code:
if (x == 3)
    tuwas();
    MachMeldung();
tuwasanderes();


Und: Schöner Fehler, den ich grade aus Versehen drin hatte:
C/C++ Code:
if (x = 3)
    tuwas();
    MachMeldung();
tuwasanderes();
C/C++ Code:
if (x = 3)
tuwas();
MachMeldung();
tuwasanderes();
C/C++ Code:
if (x = 3)
    tuwas();
    MachMeldung();
tuwasanderes();


...für runde Klammern fällt mir grade nix ein...

_________________
Das c-plusplus.de-Magazin sucht Mitmacher --- Die Artikel --- meine Homepage
pale dog
Mitglied

Benutzerprofil
Anmeldungsdatum: 27.04.2007
Beiträge: 1258
Beitrag pale dog Mitglied 13:34:49 14.06.2007   Titel:              Zitieren

estartu schrieb:

Und: Schöner Fehler, den ich grade aus Versehen drin hatte:
C/C++ Code:
if (x = 3)
    tuwas();
C/C++ Code:
if (x = 3)
tuwas();
C/C++ Code:
if (x = 3)
    tuwas();


schreib das nächste mal if (3==x)
:)

_________________
http://users.aol.com/s6sj7gt/mike666.htm
Jester
Moderator

Benutzerprofil
Anmeldungsdatum: 06.04.2001
Beiträge: 8331
Beitrag Jester Moderator 13:36:48 14.06.2007   Titel:              Zitieren

Das finde ich persönlich echt häßlich... auch wenn's gegen sowas hilft.

_________________
Mod im Mathe-Forum

Die dümmsten Programmierer schreiben die dicksten Programme.
estartu
Moderator

Benutzerprofil
Anmeldungsdatum: 05.09.2003
Beiträge: 11494
Beitrag estartu Moderator 14:00:54 14.06.2007   Titel:              Zitieren

pale dog schrieb:
estartu schrieb:

Und: Schöner Fehler, den ich grade aus Versehen drin hatte:
C/C++ Code:
if (x = 3)
    tuwas();
C/C++ Code:
if (x = 3)
tuwas();
C/C++ Code:
if (x = 3)
    tuwas();


schreib das nächste mal if (3==x)
:)
Wie schon jemand weiter oben sagte: Einige Fehler lassen sich durch Konventionen vermeiden.

Bei mir fangen alle Member mit m_ und alle Parameter mit f_ an... schon kann mir das eine genannte Beispiel nicht passieren. ;)

_________________
Das c-plusplus.de-Magazin sucht Mitmacher --- Die Artikel --- meine Homepage
Ben04
Autor

Benutzerprofil
Anmeldungsdatum: 10.10.2004
Beiträge: 1635
Beitrag Ben04 Autor 14:18:33 14.06.2007   Titel:              Zitieren

Jester schrieb:
Artchi schrieb:
Was habe ich daraus gelernt? zu jedem case überprüfe ich heute instinktiv ob ich auch ein passendes break habe. Sobald ich case schreibe, hau ich sofort ein break rein. Egal was kommt!


Genau das meine ich, sowas gehört in sonen Text auf jeden Fall mit rein.

Allerdings sollte es begründet sein und da helfen nun einmal konkrete Beispiele damit das ganze nicht in der Luft hängt und man überzeugend wirkt. Man braucht also beides.

Der erste Fehler hat bei mir dazu geführt, dass ich sobald es unerklärliche Abstürze gibt in jeden Copykonstruktor ein
C/C++ Code:
assert(&other != this);
C/C++ Code:
assert(&other != this);
C/C++ Code:
assert(&other != this);

rein tue. Hilft oft den Fehler zu finden. Einfach mit dem Debugger warten bis der assert fliegt dann noch einmal kurz einen Stacktrace und der Fehler ist behoben.


Artchi schrieb:
Kann überhaupt ein einziger Autor solch eine Liste aufschreiben? Man, der muß ja echt Probleme gehabt haben.

Natürlich kann eine solche Liste nicht komplett sein allerdings geht die Fehlersuche schneller je mehr mögliche Fehler man kennt.

Zitat:
...für runde Klammern fällt mir grade nix ein...

1 << 2&6 schreiben wo 1 << (2&6) gemeint ist. Bei solchen Operatoren setze ich auch immer Klammern.

Mir schwebte eher ein Artikel vor welcher ungewöhliche Fehler darstellt und erklärt also eher ein Kuriositätenkabinett als ein Artikel der Tipps gibt wie man Fehler verhindert. Wer kannte Bug Nummer 3 im ersten Post bevor er hier gelesen hat? Beinahe alle (alle?) Bücher sagen, dass private dazu dient die Implementation zu verstecken, also wieso sollte es einen Einfluss auf abgeleitete Klassen haben? Ich glaube da wären viele erstaunt zu sehen, dass diese Kapselung doch nicht immer so ganz dicht ist.

Das Beispiel mit if(a = 3) ist natürlich ein sehr häufiger der glaub ich bereits von jedem mindestens einmal gemacht wurde. Ein Weg ihn zuverlässig zu verhindern wäre sicher interessant hat aber in einem Kuriositätenkabinett nichts zu suchen da er allgemein bekannt ist.

Der Nutzen eines Artikels welcher sich mit der Fehlersuche allgemein beschäftigt sehe ich auch allerdings wäre das glaub ich ein anderer. Beispiel #3 hätte in dem nichts zu Suchen da es einen, in meinen Augen, wenig praxisnaher Bug ist.

Das wären dann schon zwei Vorschläge. :)
Toffifee
Mitglied

Benutzerprofil
Anmeldungsdatum: 14.06.2007
Beiträge: 1
Beitrag Toffifee Mitglied 14:35:02 14.06.2007   Titel:              Zitieren

Code:
int Koordinate[_SIZE]={0};

// später bei der Eingabe:

if( Eingabe < 0 || Eingabe > _SIZE ) WirfFehlerMeldung();
else SchreibInsArray();
Code:
int Koordinate[_SIZE]={0};

// später bei der Eingabe:

if( Eingabe < 0 || Eingabe > _SIZE ) WirfFehlerMeldung();
else SchreibInsArray();
Code:
int Koordinate[_SIZE]={0};

// später bei der Eingabe:

if( Eingabe < 0 || Eingabe > _SIZE ) WirfFehlerMeldung();
else SchreibInsArray();


Und ich such eine halbe Stunde, warum da ständig was über die Arraygrenzen rausfliegt...

Toffi
pale dog
Mitglied

Benutzerprofil
Anmeldungsdatum: 27.04.2007
Beiträge: 1258
Beitrag pale dog Mitglied 14:43:54 14.06.2007   Titel:              Zitieren

was gibt das aus?
Code:
int a = 1;
printf ("%d-%d-%d\n", a++, a++, a);
Code:
int a = 1;
printf ("%d-%d-%d\n", a++, a++, a);
Code:
int a = 1;
printf ("%d-%d-%d\n", a++, a++, a);


1-2-3 oder was anderes?
:)

_________________
http://users.aol.com/s6sj7gt/mike666.htm
CStoll
Moderator

Benutzerprofil
Anmeldungsdatum: 17.10.2005
Beiträge: 17913
Beitrag CStoll Moderator 14:57:10 14.06.2007   Titel:              Zitieren

pale dog schrieb:
was gibt das aus?
Code:
int a = 1;
printf ("%d-%d-%d\n", a++, a++, a);
Code:
int a = 1;
printf ("%d-%d-%d\n", a++, a++, a);
Code:
int a = 1;
printf ("%d-%d-%d\n", a++, a++, a);


1-2-3 oder was anderes?
:)
Und wieder ein klassisches Beispiel für undefiniertes Verhalten - dort könnte nahezu alles von 1-1-1 bis 3-3-3 hinten rauskommen (OK, mir fällt gerade keine Auswertereihenfolge ein, die letzteres produziert), je nachdem in welcher Reihenfolge der printf()-Ausdruck ausgewertet wird.

_________________
Wo ich bin, herrscht Chaos. Leider kann ich nicht überall sein.

Moderator im MFC- und C++-Board und Magazin-Autor
Jester
Moderator

Benutzerprofil
Anmeldungsdatum: 06.04.2001
Beiträge: 8331
Beitrag Jester Moderator 15:03:51 14.06.2007   Titel:              Zitieren

Ben04 schrieb:
Jester schrieb:

Genau das meine ich, sowas gehört in sonen Text auf jeden Fall mit rein.

Allerdings sollte es begründet sein und da helfen nun einmal konkrete Beispiele damit das ganze nicht in der Luft hängt und man überzeugend wirkt. Man braucht also beides.


Stimmst Du mir da zu? Ich verstehe nicht was Du damit sagen willst, klingt irgendwie als wolltest Du mir widersprechen, wobei ich da den Punkt nicht sehe. :confused:

_________________
Mod im Mathe-Forum

Die dümmsten Programmierer schreiben die dicksten Programme.
Ben04
Autor

Benutzerprofil
Anmeldungsdatum: 10.10.2004
Beiträge: 1635
Beitrag Ben04 Autor 15:29:39 14.06.2007   Titel:              Zitieren

Wollte eher verdeutlichen/betonen, dass beide Teile wichtig sind, widersprechen wollte ich eigentlich nicht. Das "Allerdings" war fehl am Platz.


Zuletzt bearbeitet von Ben04 am 15:30:21 14.06.2007, insgesamt 1-mal bearbeitet
estartu
Moderator

Benutzerprofil
Anmeldungsdatum: 05.09.2003
Beiträge: 11494
Beitrag estartu Moderator 13:58:24 22.06.2007   Titel:              Zitieren

Ich hatte heute was nettes:
C/C++ Code:
class Basis
{
public:
    virtual void tuwas(int bla);
};
C/C++ Code:
class Basis
{
public:
virtual void tuwas(int bla);
};
C/C++ Code:
class Basis
{
public:
    virtual void tuwas(int bla);
};
C/C++ Code:
class Extended : public Basis
{
public:
    virtual void tuwas(int bla);
};
C/C++ Code:
class Extended : public Basis
{
public:
virtual void tuwas(int bla);
};
C/C++ Code:
class Extended : public Basis
{
public:
    virtual void tuwas(int bla);
};
Und auf der "obersten" Ebene gibt es zig abgeleitete Klassen wie z.b.
C/C++ Code:
class Spezial : public Extended
{
public:
    virtual void tuwas(int bla);
};
C/C++ Code:
class Spezial : public Extended
{
public:
virtual void tuwas(int bla);
};
C/C++ Code:
class Spezial : public Extended
{
public:
    virtual void tuwas(int bla);
};

Und irgendwo ruft man das dann über die Basisklasse auf:
C/C++ Code:
Spezial blub;
Basis* pBasis = &blub;
pBasis->tuwas(3);
C/C++ Code:
Spezial blub;
Basis* pBasis = &blub;
pBasis->tuwas(3);
C/C++ Code:
Spezial blub;
Basis* pBasis = &blub;
pBasis->tuwas(3);
Soweit, alles prima. :live:

Nun funktioniert der Code monatelang super.
Man muss, wie das so ist immer wieder hier und da was anpassen.
Und dann mach man sowas:
C/C++ Code:
class Spezial : public Extended
{
public:
    virtual void tuwas(int bla, bool blub);
};
C/C++ Code:
class Spezial : public Extended
{
public:
virtual void tuwas(int bla, bool blub);
};
C/C++ Code:
class Spezial : public Extended
{
public:
    virtual void tuwas(int bla, bool blub);
};

Und schon tut der Aufruf nicht mehr, was man von ihm gewohnt ist. :eek:
Weil nämlich nicht wie erwartet Spezial::tuwas aufgerufen wird sondern Extended::tuwas. :warning:

Liegt eine solche Änderung auch noch mehrere Tage zurück und war wegen einer ganz anderen Funktion als da wo der Fehler auftritt, sucht man sich dumm und dusselig. :rolleyes:

_________________
Das c-plusplus.de-Magazin sucht Mitmacher --- Die Artikel --- meine Homepage
akari
Moderator

Benutzerprofil
Anmeldungsdatum: 27.11.2004
Beiträge: 11271
Beitrag akari Moderator 11:36:34 28.03.2008   Titel:              Zitieren

Hallo

ja mit dem virtual kann man tolle Fehler machen, vor allem wenn es vom Konstruktor oder Destruktor aufgerufen wird
C/C++ Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
class Base
{
  Base()
  {
    Build();
  }
  virtual void Build()
  {
    std::cout << "Base::Build" << std::endl;
  }
};

class Child : public Base
{
  Child() : Base()
  {
  }
  virtual void Build()
  {
    Base::Build();
    std::cout << "Child::Build" << std::endl;
  }  
};
...
Child test;
C/C++ Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
class Base
{
Base()
{
Build();
}
virtual void Build()
{
std::cout << "Base::Build" << std::endl;
}
};

class Child : public Base
{
Child() : Base()
{
}
virtual void Build()
{
Base::Build();
std::cout << "Child::Build" << std::endl;
}
};
...
Child test;
C/C++ Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
class Base
{
  Base()
  {
    Build();
  }
  virtual void Build()
  {
    std::cout << "Base::Build" << std::endl;
  }
};

class Child : public Base
{
  Child() : Base()
  {
  }
  virtual void Build()
  {
    Base::Build();
    std::cout << "Child::Build" << std::endl;
  }  
};
...
Child test;

Man wundert sich erstmal warum nur Base::Build aufgerufen wird...
Virtuelle Funktionen sollten niemals die Arbeit von Konstruktor und Destruktor übernehmen.

bis bald
akari

_________________
In der nächsten Version wird alles besser!
Knuddlbaer
Mitglied

Benutzerprofil
Anmeldungsdatum: 11.12.2001
Beiträge: 5237
Beitrag Knuddlbaer Mitglied 13:25:59 28.03.2008   Titel:              Zitieren

Es würde durchaus Hilfreich sein wenn man zu den geposteten Fehler mal Informationen liefert.

Wenn man vorher / nachher zeigt, wird der eigentliche Fehler nur denen klar, die danach nicht lange suchen würden. Diese Sammlung soll ja wohl weniger eine Auflistung von pralerei sein sondern anderen Helfen solche Fehler zu vermeiden. Und da ist es unumgänglich das man erläutert, wo das Problem im gezeigten Code besteht.
Ben04
Autor

Benutzerprofil
Anmeldungsdatum: 10.10.2004
Beiträge: 1635
Beitrag Ben04 Autor 16:26:44 28.03.2008   Titel:              Zitieren

C/C++ Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
1
2
3
4
5
6
7
8
9
10
11
12
13
class A{
public:
virtual void foo()const;
};

class B:public A{
public:
virtual void foo();
};

//...
const A*a=new B;
a->foo(); // Ruft A::foo und nicht B::foo auf.
C/C++ Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
class A{
public:
virtual void foo()const;
};

class B:public A{
public:
virtual void foo();
};

//...
const A*a=new B;
a->foo(); // Ruft A::foo und nicht B::foo auf.
C/C++ Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
class A{
public:
virtual void foo()const;
};

class B:public A{
public:
virtual void foo();
};

//...
const A*a=new B;
a->foo(); // Ruft A::foo und nicht B::foo auf.
Nexus
Mitglied

Benutzerprofil
Anmeldungsdatum: 16.05.2006
Beiträge: 9700
Beitrag Nexus Mitglied 09:46:29 28.05.2008   Titel:              Zitieren

Meines Erachtens wäre etwas zu Kopierkonstruktor und überladenem Zuweisungsoperator bei Klassen mit Zeigern als Membern noch nützlich... Da passiert es auch sehr schnell, dass man die Übersicht verliert.
Oder eventuell auch sonstige, häufige Zugriffsverweigerungen bei der Arbeit mit Zeigern (ich weiss jetzt gerade keine guten Beispiele). Oder Funktionen, die Referenzen auf lokale Variabeln zurückgeben, und solche Sachen...
berniebutt
Mitglied

Benutzerprofil
Anmeldungsdatum: 12.11.2007
Beiträge: 2219
Beitrag berniebutt Mitglied 08:05:36 06.09.2008   Titel:              Zitieren

"Nur triviale Programme sind völlig bugfrei zu schreiben!" Möglichkeiten für Fehler, die der Compiler und der Linker nicht erkennen, gibt es viele. Dann heisst es Debuggen und Suchen. Einen Artikel für "alles" zu schreiben, erscheint mir nahezu unmöglich. Ich hatte zu Zeiten ohne Debugger in einer Schleife den Fehler, die Laufvariable i mit der Konstante 1 zu vertauschen. Das Programm lief, nur lieferte es Schrott. Ich habe lange in den Sourcelisten gesucht und nichts gefunden. Ein Arbeitskollege wurde dann fündig. Folgerung: Wir sollten besser über Regeln zur sauberen wartungsfreundlichen Programmierung nachdenken, die wir anderen mitteilen können. Hierzu könnte ich etwas beitragen aus meinen persönlichen Programmierstil.
-fricky-
Unregistrierter




Beitrag -fricky- Unregistrierter 23:30:43 06.09.2008   Titel:              Zitieren

berniebutt schrieb:

Ich hatte zu Zeiten ohne Debugger in einer Schleife den Fehler, die Laufvariable i mit der Konstante 1 zu vertauschen.

hast du die 1 in der schleife mit einer anderer konstanten verglichen? in dem fall sollte ein guter compiler warnen, dass der vergleich immer true oder false ergibt und daher rausfliegt.

berniebutt schrieb:

Wir sollten besser über Regeln zur sauberen wartungsfreundlichen Programmierung nachdenken, die wir anderen mitteilen können.

genau. hier kommt schon mal eine regel: man wähle im editor immer einen zeichensatz, bei dem auch ein halbblinder nichts verwechseln kann.
:)
berniebutt
Mitglied

Benutzerprofil
Anmeldungsdatum: 12.11.2007
Beiträge: 2219
Beitrag berniebutt Mitglied 14:54:40 07.09.2008   Titel:              Zitieren

Das Thema "Sauberes wartungsfreundliches Programmieren" lässt sich einfach nicht mit einem einzelnen Artikel im Magazin abhandeln. Dazu ist die Aufgabe zu komplex! Es gibt aber durchaus hilfreiche Regeln, die offen diskutiert werden können.
estartu
Moderator

Benutzerprofil
Anmeldungsdatum: 05.09.2003
Beiträge: 11494
Beitrag estartu Moderator 18:07:52 07.09.2008   Titel:              Zitieren

Ja, dann immer her damit. Auch wenn sich noch kein Autor gemeldet hat, der Thread ist auch so schon interessant. :)

_________________
Das c-plusplus.de-Magazin sucht Mitmacher --- Die Artikel --- meine Homepage
berniebutt
Mitglied

Benutzerprofil
Anmeldungsdatum: 12.11.2007
Beiträge: 2219
Beitrag berniebutt Mitglied 18:54:04 07.09.2008   Titel:              Zitieren

Kann ich machen! Nur mit immer noch gültigen einfachen Regeln aus den Anfängen der Programmierung.
ghostcat
Unregistrierter




Beitrag ghostcat Unregistrierter 19:46:57 26.03.2010   Titel:              Zitieren

hey, eine Fehlersammlung!;)

Gesammelte Fehler sind gut, ich protokolliere meine eigenen so gut es geht, geht
aber aus (manchmainekstaseprogrammiergründen) nicht immer.

Fehler, die mir öfter unterlaufen u.a.:
(hier:asmcode für ein Com-Programm)

Code:
1
2
3
4
5
6
7
8
9
10
11
1
2
3
4
5
6
7
8
9
10
11
org 100h

Nachricht DB "Fehler gefunden!"

mov ah,09
mov dx,Nachricht
int 21


Ende:
int 20h
Code:
1
2
3
4
5
6
7
8
9
10
11
org 100h

Nachricht DB "Fehler gefunden!"

mov ah,09
mov dx,Nachricht
int 21


Ende:
int 20h
Code:
1
2
3
4
5
6
7
8
9
10
11
org 100h

Nachricht DB "Fehler gefunden!"

mov ah,09
mov dx,Nachricht
int 21


Ende:
int 20h




Doch mit dem sehr einsteigerfreundlichen und leistungsfähigen Flat Assembler
Fasm (hier: Fasmw) sind sind die Bugs schnell aufgepiekst...:)

Code:
1
2
3
4
5
6
7
8
9
10
11
1
2
3
4
5
6
7
8
9
10
11
org 100h                     ;256 Byte(100hex) großer Präfix wird übergangen

mov ah,09                           ;Funktion 09 gibt Zeichenkette ab Adresse
                                    ;in DX aus
mov dx,Nachricht                    ;Haustür der Zeichenkette nach DX
int 21h                             ;SystemSubroutine 21h anrufen
int 20h                             ;Systemaufruf zum Beenden für Com-Programme

Nachricht DB "Fehler gefunden!$"    ;ASCII-Datenstring, das Ende der
                                    ;Hausdurchsuchung wird mit $ bzw 24h
                                    ;markiert
Code:
1
2
3
4
5
6
7
8
9
10
11
org 100h ;256 Byte(100hex) großer Präfix wird übergangen

mov ah,09 ;Funktion 09 gibt Zeichenkette ab Adresse
;in DX aus
mov dx,Nachricht ;Haustür der Zeichenkette nach DX
int 21h ;SystemSubroutine 21h anrufen
int 20h ;Systemaufruf zum Beenden für Com-Programme

Nachricht DB "Fehler gefunden!$" ;ASCII-Datenstring, das Ende der
;Hausdurchsuchung wird mit $ bzw 24h
;markiert
Code:
1
2
3
4
5
6
7
8
9
10
11
org 100h                     ;256 Byte(100hex) großer Präfix wird übergangen

mov ah,09                           ;Funktion 09 gibt Zeichenkette ab Adresse
                                    ;in DX aus
mov dx,Nachricht                    ;Haustür der Zeichenkette nach DX
int 21h                             ;SystemSubroutine 21h anrufen
int 20h                             ;Systemaufruf zum Beenden für Com-Programme

Nachricht DB "Fehler gefunden!$"    ;ASCII-Datenstring, das Ende der
                                    ;Hausdurchsuchung wird mit $ bzw 24h
                                    ;markiert


Los Leute, sammelt mit, jetzt zur Osterzeit macht doch die Sucherei besonders viel Spaß ;)
Spacemuck
Mitglied

Benutzerprofil
Anmeldungsdatum: 19.12.2005
Beiträge: 221
Beitrag Spacemuck Mitglied 16:12:18 13.05.2010   Titel:              Zitieren

C/C++ Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
1
2
3
4
5
6
7
8
9
10
11
12
13
...
class abc
{
 public:
  abc();
 
  void A();
  void B();

 private:
  int i;
}    //Hier wurde das Semikolon vergessen
...
C/C++ Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
...
class abc
{
public:
abc();

void A();
void B();

private:
int i;
} //Hier wurde das Semikolon vergessen
...
C/C++ Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
...
class abc
{
 public:
  abc();
 
  void A();
  void B();

 private:
  int i;
}    //Hier wurde das Semikolon vergessen
...


Dank des fehlenden Semikolons hab ich teilweise schon Stunden gebraucht wo der Fehler liegt, da der abgebrochene Kompiliervorgang mir mit einem Fehler in einer Methode quittiert wurde..

_________________
Wikipedia
MSDN
...
C/C++ Forum :: Allgemeines zum Magazin ::  [Suchen Autor für:] Bugs bei denen man lange sitzt   Auf Beitrag antworten

Zeige alle Beiträge auf einer Seite




Nächstes Thema anzeigen
Vorheriges Thema anzeigen
Sie können Beiträge in dieses Forum schreiben.
Sie können auf Beiträge in diesem Forum antworten.
Sie können Ihre Beiträge in diesem Forum nicht bearbeiten.
Sie können Ihre Beiträge in diesem Forum nicht löschen.
Sie können an Umfragen in diesem Forum nicht mitmachen.

Powered by phpBB © 2001, 2002 phpBB Group :: FI Theme

c++.de ist Teilnehmer des Partnerprogramms von Amazon Europe S.à.r.l. und Partner des Werbeprogramms, das zur Bereitstellung eines Mediums für Websites konzipiert wurde, mittels dessen durch die Platzierung von Werbeanzeigen und Links zu amazon.de Werbekostenerstattung verdient werden kann.

Die Vervielfältigung der auf den Seiten www.c-plusplus.de, www.c-plusplus.info, www.c-sar.de, www.c-plusplus.net und www.baeckmann.de enthaltenen Informationen ohne eine schriftliche Genehmigung des Seitenbetreibers ist untersagt (vgl. §4 Urheberrechtsgesetz). Die Nutzung und Änderung der vorgestellten Strukturen und Verfahren in privaten und kommerziellen Softwareanwendungen ist ausdrücklich erlaubt, soweit keine Rechte Dritter verletzt werden. Der Seitenbetreiber übernimmt keine Gewähr für die Funktion einzelner Beiträge oder Programmfragmente, insbesondere übernimmt er keine Haftung für eventuelle aus dem Gebrauch entstehenden Folgeschäden.