Es ist gar nicht so einfach Programme zu schreiben, die den Comnpiler wirklich zufrieden stellen. Im Regelfall faellt das gar nicht auf, weil man die Warnungsstufe so einstellt, dass viele Warnungen einfach unterdrueckt werden. Schraubt man die Stufe langsam hoch kann es passieren, dass Warnungen erscheinen von denen man sich nicht sicher ist, wie man die los werden soll. So zum Beispiel folgende Konstruktion:
void func1(char *format){
printf( "%25s\n", format );
}
void func2(const char *format){
func1( format );
}
Dieser Code wirft beim Uebersetzen in Zeile 6 die Warnung, dass der Funktionsaufruf den Vermerk 'const' des Pointerparameters ungueltig macht
warning: passing argument 1 of 'func1' discards qualifiers from pointer target type. Klar, format ist als const definiert und wird danach als veraenderbar weiter gegeben. Sei nun func1() in einer Bibliothek definiert und damit unantastbar, obwohl man weiss dass format darin nie geaendert wird. In func2 moechte man das const aber auch nicht entfernen, da format auch gerne mal ein Stringliteral ist und das sollte dringend nicht veraenderbar sein. Die Loesung sieht, grosszuegig geklammert, wie folgt aus:
void func2(const char *format){
func1( *((char**)((int)&format)) );
}
Auf den ersten Blick kann man das natuerlich wegkuerzen, da wird aus einem char* ein char* gemacht. Tatsaechlich allerdings wird erstmal aus der Adresse des Pointers ein int gemacht. Damit geht die Information des originalen Datentypen verloren, vor allem dass es sich um eine const handelt. Da wir aber einen char* brauchen, aus den man auch mal ein strlen() anwenden kann, muss aus dem int wieder ein char** gemacht werden und dieser wir dereferenziert. Ganz einfach.
Nur was spricht nun dagegen einfach (char*)((int)format) zu verwenden?
Kommentare