MALLOC_DEBUG

2. Juli 2009 von iceboy

Das wohl größte Problem bei Anwendungen in C ist .... na was wohl .... der Umgang mit dem Speicher. Zu wenig allokiert, nicht freigegeben, freigegeben und dann doch beschrieben, ect.

Solche Fehler zu finden kann aufwendig sein, muss es aber nicht!

Ich verwende die "Malloc Debug Library" damit geht das leicht von der Hand. Zu finden hier: http://www.hexco.de/rmdebug/index.html

Offtopic: Toolliste

15. Juni 2009 von iceboy

Ich habe mal eine Toolliste für alle mögliche erstellt, zu der auch jeder etwas hinzufügen kann.

Zu finden ist die Liste hier: http://tools.bilger.info

Asserts sind schön und gut, aber…

4. Juni 2009 von ehhm

... man kann es auch übertreiben:

 
const std::string& GetLabel( unsigned int ind ) const
{
  ASSERT( ind >= 0 && ind < GetCount() );
  return Item(ind).GetText();
}
 

Die Assertion enthält einen unnötigen Vergleich wodurch eine unnötige Kompilerwarnung generiert und ein Entwickler, der den Code nur liest, verwirrt wird. Im schlimmsten Fall wiegt er sich in falscher Sicherheit und die Assertion geht genau in die falsche Richtung.

Also lieber so:

 
const std::string& GetLabel( unsigned int ind ) const
{
  ASSERT( ind < GetCount() );
  return Item(ind).GetText();
}
 

und den Compiler die Sache mit der Typ- bzw. Bereichsprüfung überlassen; der kann das eh viel besser.

Kennt jemand das ififif Konstrukt?

3. Juni 2009 von iceboy

Ich habe heute mal wieder was neues kennen gelernt :P
Das ififif. Es sieht so aus:

 
if (qir & QIR_WCEF)
if (qir & QIR_ABRT)
if (qir & QIR_SPIF) {
  wake_up(&wqueue);
}
 

Sieht fast so aus, als hätte da jemand was vergessen, ich halte es für fast unlesbar, und würde es deshalb vorziehen, das so zu machen:

 
if ((qir & QIR_WCEF) && (qir & QIR_ABRT) && (qir & QIR_SPIF)) {
  wake_up(&wqueue);
}
 

[UPDATE:]
Oder (in diesem Fall) noch besser:

 
if ((qir & (QIR_WCEF| QIR_ABRT| QIR_SPIF)) {
  wake_up(&wqueue);
}
 

Zudem bevorzuge ich ganz klar camelCasing für Funktionsnamen, aber das war hier eher Nebensache.

Ausblick: Ich möchte in nächster Zeit eine paar CodingGuidelines für C zusammenstellen, die ich dann hier vorstellen werde, jeweils mit Begründung, warum genau so.
[/UPDATE]

Urlaub

25. Mai 2009 von iceboy

So, ich genieße gerade meine Urlaub, daher kommt hier auch gerade nichts neues, aber ab dem 2.6 geht's wieder weiter ...

XML - XML Macht Lustig?

23. Mai 2009 von iceboy

Da bin ich mir nicht sicher, aber XML ist eigentlich kein rekursives Akronym. Dafür unterstützt das XML Format durchaus die Möglichkeit der Rekursion und noch viele andere unglaubliche Sachen, die man aber auch ganz toll nicht verwenden kann.

So kann man z.B. ganz auf den Inhalt von Tags verzichten, wenn man alle Werte in die Attribute schreibt.

Oder auch eine ganz wunderbare Idee die mir schon mal begegnet ist:

 
<Koordinaten>
  <Koordinate>3.5</Koordinate>
  <Koordinate>17</Koordinate>
  <Koordinate>23.25</Koordinate>
</Koordinaten>
 

Das Problem hierbei ist nur, dass es auf die Reihenfolge der Koordinaten ankommt und der Parser die Reihenfolge ignoriert (was ja legitim ist).

Wieder so ein Fall von "das hört sich gut an, das verwenden wir" und "XML, ja hab ich schon mal gesehen".
Richtig spannend wird XML doch eh erst mir XPath Expressions, aber dazu vielleicht ein ander mal mehr.

Formatierung: schlecht, besser, OO

22. April 2009 von iceboy

Jetzt ist mir schon wieder etwas aufgefallen, was man anderst und meiner Meinung nach besser machen könnte. Hier der originale Code:

 
long theRest = theMinutes % 60;
long theHours = theMinutes / 60;
if (theRest < 10) {
	theBuffer.append(theHours + ":0" + theRest + " h");
} else {
	theBuffer.append(theHours + ":" + theRest + " h");
}
 

Und hier mein Verbesserungsvorschlag:

 
theBuffer.append(theHours + ":");
if (theRest < 10) {
	theBuffer.append("0");
}
theBuffer.append(theRest + " h");
 

oder die wohl schönste Variante die Java bietet:

 
theBuffer.append();
Formatter formated = new Formatter("02d", theRest);
theBuffer.append(theHours + ":" + formated + " h");
 

Wo soll man nur Anfangen …

20. April 2009 von iceboy

... mit dem meckern, wenn man solch einen Code liest. Das die Aufregung nicht vollkommen umsonst ist, beschreib ich hier mal was ich vorgefunden habe.

Hier die zwei Klassen:

public class A{
  private ILogger myLogger;
  private B myB;
  public A(ILogger logger, B theB){
    myLogger = logger;
    myB = theB;
  }
  public Data fctOne(Data one, Data two){
    return one + two  + myB.getConfig().anything;
  }
  public Data fctTwo(Data one, Data another){
    return one + another  + myB.getConfig().something;
  }
}
 
 
public class B{
  public class Configuration{
    public Data anything;
    public Data something;
  }
  private ILogger myLogger;
  private int myMember;
  private Configuration config;
  private A myA;
  public B(ILogger logger, Configuration conf){
    myLogger = logger;
    config = conf;
    myA = new A(logger, this);
  }
  public Data fctOne(Data one, Data two){
    Data result = A.fctOne(one, two);
    return SomeClass.doSomething(result);
  }
  public Data fctTwo(Data one, Data another){
    Data result = A.fctTwo(one, another);
    return SomeClass.doSomething(result);
  }
  public Configuration getConfig(){
    return config;
  }
}

So fangen wir mal an:

  1. Wieso wurden diese Klassen getrennt? Die Klasse A übernimt die Aufbereitung der Daten, die Klasse B speichert die Konfiguration und ruft Funktionen der Klasse A auf. Das ist an und für sich nicht problematisch, es wird jedoch zum Problem, wenn man sich die Klasse A genauer anschaut.Es werden in den Funktionen der Klasse A lediglich die Parameter und Daten die in der Klasse B gespeichert sind verwendet.Da sollte einem in den Sinn kommen, die Klasse A in die Klasse B zu integrieren.
  2. Öffentliche Member Die Klasse Configuration enthält öffentliche Member. WTF! Welche begründung gibt es hierfür? Getter und Setter kann man mit Eclipse sogar automatisch generieren, da muss man nicht mal denken, geschweige denn programmieren! Zudem hat die Klasse B ja auch einen Getter, somit kann das Prinzip nicht ganz in vergessenheit geraten sein.
  3. Nicht verwendete Member Wieso legt man sich eine Membervariable an, die man nicht verwendet? Der Konstruktor kann den Übergabeparameter ILogger ja behalten, um die Möglichkeit zu erhalten den Logger später noch zu verwenden.

Das einzige was positiv an dem Code aufgefallen ist, ist dass sich der Autor im Javadoc Kommentar verewigt hat! *evil*

Der Erste

20. April 2009 von ehhm

Programming DAD (Does and Donts)  soll uns die Möglichkeit geben, unseren täglichlichen Frust im Umgang mit fremdem oder altem Quellcode ein Ventil zu bieten und damit auch andere etwas davon haben (in der Hoffnung ein bischen Wissen zu verbreiten) werden wir es hier niederschreiben. Gewürzt mit dem ein oder anderen HOWTO zu verschiedenen Themen der Softwareentwicklung und Serveradministration wird es ein spannender Blog für Jung und Alt.

Wir, das sind Andreas "ehhm" Küchler und Matthias "iceboy" Bilger. Unseres Zeichens Softwareentwickler, Freizeit-Admins und was sonst noch so dazu gehört.

Die Idee zu diesem Blog entstand an einem sonnigen Freitag im April des Jahres 2009, als einer von uns über einem alten Javaquellcode brütete und sich fragte, warum jeder Idiot Software entwickeln darf...