Forum: Compiler & IDEs C Projekt entmüllen - wie?


von Micha (Gast)


Lesenswert?

Ich bastel aktuell an einem AVR-GCC Projekt das so langsam aus den 
Nähten quillt - mehrere eingebundene (Quelltext-) Bibliotheken, 
funktional hat sich im Laufe der Bearbeitung auch vieles geändert. Wie 
durch ein Wunder funktioniert das Ganze, obwohl ich eigentlich längst 
den Überblick verloren hab, welcher Code noch wirklich dazu gehört und 
welche Teile der Quelltexte nur noch "toter Ballast" sind.

Gibts eigentlich einen formalen Ansatz, um ungenutzte Funktionen sowie 
globale Variablen in einem komplexen C Projekt zu identifizieren? Ich 
würde den Code gern "verschlanken", insbesondere auch die Bibliotheken 
auf den tatsächlich genutzen Umfang zurechtstutzen.

von Kaj (Gast)


Lesenswert?

Micha schrieb:
> Gibts eigentlich einen formalen Ansatz, um ungenutzte Funktionen sowie
> globale Variablen in einem komplexen C Projekt zu identifizieren?
Compiler warnungen als errors behandeln lassen, und auf pedantic 
stellen, dann sagt der schon welche Variablen nicht benutzt werden.

von Dirk B. (dirkb2)


Lesenswert?

Du kannst z.B. auch mal Doxygen über das Projekt laufen lassen.
Mit den Call- und Callergraphen bekommst du auch  einen Überblick, 
welche Funktionen von anderen Funktionen aufgerufen werden.

Zudem kannst du damit auch gleich die Dokumentation erstellen.

von Takao K. (takao_k) Benutzerseite


Lesenswert?

Also normalerweise bindet ein C compiler nicht genutzte Funktionen 
garnicht ein. Was du mit ungenutzten Variablen wirklich sparen kannst 
haelt sich in Grenzen. Wenn du noch RAM frei hast ist es total egal, 
ansonsten nimm einen Chip mit mehr Speicher.

von Salewski (Gast)


Lesenswert?

Takao K. schrieb:
> Also normalerweise bindet ein C compiler nicht genutzte Funktionen
> garnicht ein.

Bei AVR-GCC ist das nicht so einfach

http://www.mikrocontroller.net/articles/GCC:_unbenutzte_Funktionen_entfernen

von Takao K. (takao_k) Benutzerseite


Lesenswert?

Salewski schrieb:
> Takao K. schrieb:
>> Also normalerweise bindet ein C compiler nicht genutzte Funktionen
>> garnicht ein.
>
> Bei AVR-GCC ist das nicht so einfach
>
> http://www.mikrocontroller.net/articles/GCC:_unbenutzte_Funktionen_entfernen

PIC32 benutzt gcc und wenn ich eine Funktion nicht verwende, ist der 
erzeugte code kleiner, macht nichts, kann man einfach drinlassen. Das 
ist ja die idee mit den .H dateien, also dass nur ein Prototyp 
uebergeben wird, und die Funktion wird dann bei Bedarf hinzugelinkt.

Einfach mal ausprobieren, also eine lib die nur ein paar Funktionaufrufe 
hat, diese auskommentieren. Sollte dann einige K weniger sein.

Also dass waere ja eine Katastrophe wenn man dass jedesmal manuell 
machen muesste.

von ich (Gast)


Lesenswert?

Salewski schrieb:
> Takao K. schrieb:
>> Also normalerweise bindet ein C compiler nicht genutzte Funktionen
>> garnicht ein.
>
> Bei AVR-GCC ist das nicht so einfach
>
> http://www.mikrocontroller.net/articles/GCC:_unben...


Wenn ich das richtig interpretiert habe, war das nicht so einfach, 
aber mittlerweile schon. Sehe ich das richtig?
> Die Standard-Linkerscripts aktueller GCC-Distributionen
> (WinAVR, WinARM) sind bereits entsprechend angepasst.

von Oliver S. (oliverso)


Lesenswert?

Jeder anständige Editor bietet eine Suchfunktion über das ganze Projekt. 
Schah halt nach, ob die fraglichen Funktionen irgend auftauchen. 
Alternativ einfach mal auskommentieren. Compiler/Linker sagt dir dann 
schon, wenn was fehlt.

Oliver

von Linker Locator (Gast)


Lesenswert?

Takao K. schrieb:
> Also normalerweise bindet ein C compiler nicht genutzte Funktionen
> garnicht ein. Was du mit ungenutzten Variablen wirklich sparen kannst
> haelt sich in Grenzen. Wenn du noch RAM frei hast ist es total egal,
> ansonsten nimm einen Chip mit mehr Speicher.

Der C Compiler bindet nicht, das macht der Linker.

Der Compiler packt alles aus einem c file in ein object file. Der Linker 
bindet die einzelnen oject files zu einem. Da ist alles drin!
Einen Unterschied gibt es bei den Libs. Aus einer lib holt der Linker 
nur, was auch aufgerufen wird.

von Kaj (Gast)


Lesenswert?

Takao K. schrieb:
> Was du mit ungenutzten Variablen wirklich sparen kannst
> haelt sich in Grenzen. Wenn du noch RAM frei hast ist es total egal,
> ansonsten nimm einen Chip mit mehr Speicher.
Dem TO geht es doch gar nicht darum speicher auf dem mC einzusparen. Der 
TO will sein Projekt aufräumen (Code entfernen der nicht mehr verwendet 
wird) um es wieder übersichtlicher zu machen, nicht weil der mC zu klein 
ist.

von Robert N. (metrux)


Lesenswert?

Taktiken zum Aufräumen:

A. wegwerfen und neu machen.

Man weiß ja jetzt was man wirklich wollte und hat es schon einmal 
gemacht, kann es deshalb normalerweise besser

B. Das entsorgen was man nie anfasst und nie braucht.

Man löscht immer mehr und dann fehlt einem Minuten später irgendwas ganz 
wichtiges.

C. Das zusammenfassen was man braucht und Ordnen.

Meistens hält man viel zu viel für wichtig und behält dann doch zu viel.


Auswahl der Richtigen Methode? Mach dir einen Plan ob nun auf Papier, 
mit Doxygen oder wenn man kann im Kopf ist egal.

Modularisieren: Das was zusammen gehört, gehört auch zusammen gelagert.
Abstrahieren: Dinge die die gleicht Funktion erfüllen nur einmal 
aufbewahren.

Versionskontrolle (git, svn) benutzen und oft einchecken, so kann man 
nach nachvollziehen was man gemacht hat und zu jedem Punkt zurück.

Wenn du aber selbst deine Werkstatt nie benutzt woher sollst du dann 
wissen was wichtig ist und das nicht?

Nun kann man sich überlegen ob man "oben" oder "unten" anfängt, d.h. ob 
man mit konkreten Funktionen anfängt "berechne nächste Vorhersage(int 
a,...., float z)" oder "addiere(int a, int b)"

: Bearbeitet durch User
von Marc P. (marcvonwindscooting)


Lesenswert?

Robert N. schrieb:
> A. wegwerfen und neu machen.

Er schreibt das nicht umsonst als ersten Vorschlag ;-)

Und beim 'neu machen' gleich mal darauf achten, dass man universell 
einsetzbare Funktionen als Bibliotheksfunktion macht, also ein *.h mit 
den Prototypen UND GANZ WICHTIG gescheite Doku dazu. Ein *.c enthaelt 
dann den Code der Funktion, sofern die nicht so einfach ist, dass man 
sie besser als inline static in der *.h implementiert.

Davor steht eigentlich die Festlegung deiner eigenen Regeln. Wie werden 
Funktionen genannt? Init_I2C() oder I2C_Init() ?
Wie kommen die Parameter in der Reihenfolge?
Also ich verwende grob sowas:
Modul: fifo
=> Header = fifo.h
=> Funktionen heissen fifoXXX
=> mit erstem Parameter stets der Fifo,
=> Parameter links sind 'wichtiger' als die weiter rechts, d.h. der 
nat"urliche Nachdenkprozess 'was brauch ich?' liefert sie in der 
Reihenfolge in der sie geschrieben werden.

Die Idee dahinter ist - wenn man so ein schlechtes Gedaechtnis hat wie 
ich - die eigenen Funktionsnamen, Datentypen und Dateinamen zu erraten 
nachdem man sie vergessen hat ;-)

Aehmmmm, was wollte ich eigentlich sagen...?

: Bearbeitet durch User
von Oliver S. (oliverso)


Lesenswert?

Marc P. schrieb:
> Robert N. schrieb:
>> A. wegwerfen und neu machen.
>
> Er schreibt das nicht umsonst als ersten Vorschlag ;-)

Ist allerdings Unsinn. Es ist ganz normle Praxis beim Programmieren, ab 
und zu mal seinen Code aufzuräumen, ohne immer gleich alles von ganz 
vorne neu zu schreiben.

Oliver

von Simon K. (simon) Benutzerseite


Lesenswert?

Oliver S. schrieb:
> Marc P. schrieb:
>> Robert N. schrieb:
>>> A. wegwerfen und neu machen.
>>
>> Er schreibt das nicht umsonst als ersten Vorschlag ;-)
>
> Ist allerdings Unsinn.
Nö ist es nicht. Schlage ich auch vor.

> Es ist ganz normle Praxis beim Programmieren, ab
> und zu mal seinen Code aufzuräumen, ohne immer gleich alles von ganz
> vorne neu zu schreiben.
Also unter aufräumen (kleine lokale Quellcodebaustelle) verstehe ich was 
gänzlich anderes, als entmüllen (viel Müll im gesamten Quellcode und 
kein Überblick mehr).

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.