1. Macht es Sinn grundsätzlich zu jedem ".c"-Sourcefile ein ".h"-File
mit anzulegen (egal, ob's benötigt wird oder nicht)?
2. Was hat es für Nachteile, wenn grundsätzlich jede Funktion (egal,
ob sie lokal oder global benötigt wird) als extern deklariert wird?
3. Ist es sinnvoll alle "includes" in einer seperaten Datei abzulegen,
und dann im entsprechenden Sourcefile nur diese eine Datei zu
includieren, anstatt in jedem Sourcefile eine Liste der Dateien
anzulegen, die wirklich benötigt werden?
Beispiel:
"ALLINCLUDES.H": #include "source1.h"
#include "source2.h"
#include "source3.h"
"SOURCE1.C": #include "allincludes.h"
"SOURCE2.C": #include "allincludes.h"
"SOURCE3.C": #include "allincludes.h"
4. Verwendet Ihr "ungarische Notation"?
P.S.: Ist mir schon klar, dass vieles Geschmacksache ist ;-)
ungarische Notation...
die altert mir zu schnell. Bleibt zu überlegen, sie jeweils erst zu
einem Release automatisch generieren zu lassen, falls sie gewünscht
wird.
> 1. Macht es Sinn grundsätzlich zu jedem ".c"-Sourcefile ein ".h"-File> mit anzulegen (egal, ob's benötigt wird oder nicht)?
Noe, aber es macht sinn so zu programmieren das es benoetigt wird!
> 2. Was hat es für Nachteile, wenn grundsätzlich jede Funktion (egal,> ob sie lokal oder global benötigt wird) als extern deklariert wird?
Du solltest nur Funktionen die auch in anderen Teilen deines Programms
benoetigt werden ueber das Headerfile exportieren.
Einer der Vorteile darin ein Project in kleine Sourcefiles aufzuteilen
besteht darin das du diese Files irgendwann man in verschiedenen
Projekten verwenden kannst. Es koennte dir dann passieren das du
verschiedene Funktionen gleichen Namens hast. Das ist zwar generell
nicht so empfehlenswert, aber wenn so eine Funktion nur lokal benutzt
wird is es IMHO okay.
> includieren, anstatt in jedem Sourcefile eine Liste der Dateien> anzulegen, die wirklich benötigt werden?
Immer nur das importieren was du brauchst! Du musst dir darueber im
klaren sein was dein Programm benoetigt und was nicht. Gib nicht das
denken in automatischen Structuren ab indem du einfach alles
importierst.
Es kann z.B interessant enden wenn du irgendwo in deinem Header ein
#define stehen hast das du vor Jahren mal geschrieben hast und woran du
nicht mehr denkst, das die jetzt aber deinen Source umschreibt ohne das
du es merkst.
> 4. Verwendet Ihr "ungarische Notation"?
Noe, aber ich esse auch keine kleinen Kinder. :-)
Olaf
4. Verwendet Ihr "ungarische Notation"?
4. Verwendet Ihr "ungarische Notation"?
4. Verwendet Ihr "ungarische Notation"?
4. Verwendet Ihr "ungarische Notation"?
> 4. Verwendet Ihr "ungarische Notation"?> 4. Verwendet Ihr "ungarische Notation"?> 4. Verwendet Ihr "ungarische Notation"?> 4. Verwendet Ihr "ungarische Notation"?
Nein, ich stottere noch nicht. Das sind einfach die Nachteile eines
primitiven HTML-Interfaces im vergleich zu einem guten Newsreader
mit Emacs als Editor. <seufz>
Olaf
>Nein, ich stottere noch nicht. Das sind einfach die Nachteile eines>primitiven HTML-Interfaces im vergleich zu einem guten Newsreader>mit Emacs als Editor. <seufz>
Kannst es nur nicht richtig bedienen.....
> Macht es Sinn grundsätzlich zu jedem ".c"-Sourcefile ein ".h"-File
Ich halte nichts davon, aber das hängt vom Editor ab (wenn der falten
kann, ist die Aufteilung in viele h-Files sehr hinderlich, aber bei
einem Editor ohne dieses Feature verliert man in langen h-Dateien die
Übersicht, dann sind kleine h-Dateien zu bestimmten Schwerpunkten
übersichtlicher).
Was mir ein grosser Graus ist: trivialer Code, der durch sinnfreie
Kommentare und Unterteilung in 25 Header auf das zehnfache aufgebläht
wurde und erst übersichtlich und verständlich wird, wenn man das
Kommentar-Gestrüpp gelöscht hat und alle Header zusammenfasst.
> Was hat es für Nachteile, wenn grundsätzlich jede Funktion (egal, ob sie lokal
oder global benötigt wird) als extern deklariert wird?
Für kleine Projekte sehe ich keine Nachteile. Die Übersichtlichkeit
("diese Funktion wird nur lokal benötigt") gewinnt dadurch nur minimal.
> Ist es sinnvoll alle "includes" in einer seperaten Datei abzulegen und dann im
entsprechenden Sourcefile nur diese eine Datei zu includieren
Jede Sourcedatei mit einer unterschiedlichen Aufreihung von Includes zu
beginnenen, wirkt auf mich etwas chaotisch. Besser ist es, alles in eine
defs.h zu packen und (nur) diese in jedem Source-Code des Projekts zu
inkludieren. Wenn der verwendete Compiler vorkompilierte Header
unterstützt, kann man so den Compilevorgang stark verkürzen.
> 4. Verwendet Ihr "ungarische Notation"?
Das ist was für Erbsenzähler.
@dietmar
>Jede Sourcedatei mit einer unterschiedlichen Aufreihung von Includes zu>beginnenen, wirkt auf mich etwas chaotisch. Besser ist es, alles in eine>defs.h zu packen und (nur) diese in jedem Source-Code des Projekts zu
so mache ich das mittlerweile schon seit einigen jahren. alle benötigten
includes in einer header datei rein (bei mir heißt die dann lib.h) und
von jedem c-file aus wird diese datei included. geht gut und verursacht
keine probleme
>inkludieren. Wenn der verwendete Compiler vorkompilierte Header>unterstützt, kann man so den Compilevorgang stark verkürzen.
das geht nicht nur mit vorkompilierten headern. es ließen sich ja auch
alle c-files (z.b. in einer lib.c) includieren. ist aber nicht sehr
ratsam (obwohl deutlich schnellere compilierzeiten)
Dietmar E wrote:
>> Ist es sinnvoll alle "includes" in einer seperaten Datei abzulegen und dann im> entsprechenden Sourcefile nur diese eine Datei zu includieren>> Jede Sourcedatei mit einer unterschiedlichen Aufreihung von Includes zu> beginnenen, wirkt auf mich etwas chaotisch. Besser ist es, alles in eine> defs.h zu packen und (nur) diese in jedem Source-Code des Projekts zu> inkludieren. Wenn der verwendete Compiler vorkompilierte Header> unterstützt, kann man so den Compilevorgang stark verkürzen.>
Dann hast du noch nie mittlere bis grosse Projekte bearbeitet.
Denn da ist das, was du da erzählst absoluter Schwachsinn.
Ein mittleres Projekt beginnt bei mir bei ca. 500 *.c/*.h
Files. Ein grosses bei etwa 1000.
> das geht nicht nur mit vorkompilierten headern. es ließen sich ja auch> alle c-files (z.b. in einer lib.c) includieren. ist aber nicht sehr> ratsam (obwohl deutlich schnellere compilierzeiten)
Also fuer die Behauptung solltest du jetzt aber nochmal eine Erklaerung
liefern.
Meine Projekte bestehen je nach Groesse aus 20 bis 100 einzelnen Files.
Wenn ich daran arbeite dann aender ich meist nur in 1-2Files was und
dann werden auch nur die neu uebersetzt. Das geht erheblich schneller
als ein make all.
Olaf
Und noch 'ne Meinung:
>1. Macht es Sinn grundsätzlich zu jedem ".c"-Sourcefile ein ".h"-File> mit anzulegen (egal, ob's benötigt wird oder nicht)?
Radio Eriwan .. es kommt darauf an.
Warum teilt man überhaupt den Code in mehrere Sourcefiles auf? Sinn
macht das, wenn sich dadurch (evtl. wiederverwendbare)
Funktionseinheiten, logische Funktionseinheiten, Libraries, o.ä. bilden
lassen. Die .h-Files sind dann die "Interfacedefinitionen" dazu, welches
den öffentlichen Teil der .c-Datei anderen per "extern ..." bekannt
macht. Beispielsweise eine source-Datei lcd.c mit allen Funktionen zur
Ansteurung eines lcds, dazu ein lcd.h. Ohne Interface ist keine
sinnvolle Nutzung eines solchen Moduls möglich, also gehört zu jeder
.c-Datei eine .h-Datei.
Keine Regel ohne Ausnahme, manchmal ist es sinnvoll, zu mehreren
.c-Dateien nur eine .h-Datei zu haben, z.B. bei libraries.
>2. Was hat es für Nachteile, wenn grundsätzlich jede Funktion (egal,> ob sie lokal oder global benötigt wird) als extern deklariert wird?
Bei einer sauberen Definition des Interfaces stellt sich die Frage
nicht. Per "extern" wird genau das nach aussen sichtbar gemacht, was
sichtbar sein soll. Mehr nicht.
>3. Ist es sinnvoll alle "includes" in einer seperaten Datei abzulegen,> und dann im entsprechenden Sourcefile nur diese eine Datei zu> includieren, anstatt in jedem Sourcefile eine Liste der Dateien> anzulegen, die wirklich benötigt werden?
Ich persönlich vermeide geschachtelte includes, wo immer möglich.
>4. Verwendet Ihr "ungarische Notation"?
Nö.
Oliver
> Keine Regel ohne Ausnahme, manchmal ist es sinnvoll, zu mehreren> .c-Dateien nur eine .h-Datei zu haben, z.B. bei libraries.
In diesem Sonderfall habe ich dann auch eine einzige Header Datei
passend zu Libary. Dort werden dann aber die einzelnen Headerdateien des
Libariesource includiert.
So muss ich dann fuer eine Libary die ich benutzen will und die sich nur
selten mal aendert nur ein include einfuegen, habe aber andererseits den
Vorteil das sich die Datei immer auf dem aktuellesten Stand befindet
wenn ich etwas an der Libary verbessern oder einfuegen sollte.
Olaf
> Dann hast du noch nie mittlere bis grosse Projekte bearbeitet
Ich bin der Entwickler von CubicIDE, einer führenden C/C++
Entwicklungsumgebung für Amiga/MorphOS Computer, Umfang ca 300 MB,
Sourecode der Kern-IDE ca 8 MB (im Moment ist die Webseite leider
offline, Server-Problem). Ich habe vermutlich mehr Code geschrieben, als
alle Leute in diesem Thread zusammen :)
So, jetzt will ich auch noch mein Senf dazugeben.
Ich persönlich finde, dass es Sinn macht, seinen Code in mehrere Source-
und dazugehörige Header-Files zu unterteilen. Natürlich sollte man das
auch nicht übertreiben und für jede Funktion ein Source- und Header-File
anlegen. Aber man packt zum Beispiel die USART-Funktionen in ein C-File
und ein dazügehöriges H-File und dann kann man seine Display-Lib auch in
ein eigenes C-File und H-File packen und so weiter. So weiss man immer,
aha, ich will eine USART-Funktio --> in zB. usart.h nachschauen und so
weiter. Natürlich gehört auch zu jeder Funktion eine anständige Doku die
jeden Parameter und auch den Return immer schön sauber beschreibt, so
dass ich diese Funktionen auch noch in einem Jahr wieder verwenden kann,
ohne zuerst genaustens meine Source studieren zu müssen.
Und noch ein Wort zur ungarischen Notation. Ich persönlich verwende sie
und finde, dass sie mir hilft, vorallem auch beim Coden. Es ist jedoch
nicht das wichtigste um einen übersichtlichen Code zu schreiben. Viel
wichtiger ist, dass man jeder Variable einen sinnvollen Namen gibt.
So, jetzt wisst ihr's ;-)
Sputnik
Dietmar E wrote:
>> Dann hast du noch nie mittlere bis grosse Projekte bearbeitet>> Ich bin der Entwickler von CubicIDE, einer führenden C/C++> Entwicklungsumgebung für Amiga/MorphOS Computer, Umfang ca 300 MB,> Sourecode der Kern-IDE ca 8 MB (im Moment ist die Webseite leider> offline, Server-Problem).
Und warum verzapfst du dann so einen Scheiss, dass es vernünftig
ist alle includes in ein 'Ueber-Include' zusammenzufassen und
nur dieses zu verwenden?
Damit führst du jeden make bzw. jedes make Generiertool
ad absurdum.
Um mein letztes Projekt komplett zu compilieren, ist die
Maschine etwas über eine Stunde beschäftigt.
Wenn du wirklich wegen jeder kleinsten Änderung in jedem
kleinsten Header File eine Compiletime von 1 Stunde
akzeptabel findest anstelle von ein paar Sekunden bzw
Minuten für nur die Teile die geändert wurden bzw. davon
abhängig sind, dann ....
> Ich habe vermutlich mehr Code geschrieben, als> alle Leute in diesem Thread zusammen :)
Das du dich mal nicht täuscht.
Nachtrag:
Aber vielleicht reden wir ja aneinander vorbei.
Es geht um die Situation:
3 *.c Files
foo1.c
1
#include"foo1.h"
2
3
voidfoo1()
4
{
5
}
foo2.c
1
#include"foo2.h"
2
3
voidfoo2()
4
{
5
}
main.c
1
#include"foo1.h"
2
#include"foo2.h"
3
4
intmain()
5
{
6
foo1();
7
foo2();
8
}
samt zugehörigen Header Files:
foo1.h
1
#ifndef FOO1_H_INCLUDED
2
#define FOO1_H_INCLUDED
3
voidfoo1(void);
4
#endif
foo2.h
1
#ifndef FOO2_H_INCLUDED
2
#define FOO2_H_INCLUDED
3
voidfoo2(void);
4
#endif
Ändere ich die Funktion foo2 um, so dass sie einen zusätzlichen
int als Argument nimmt, dann wird vom make neu compiliert:
foo2.c und main.c. Soweit so gut
Führe ich aber einen Überheader ein
def.h
1
#include"foo1.h"
2
#include"foo2.h"
und halte mich konsequent an die Vorgabe und tausche alle
#includes in den *.c gegen ein #include "defs.h" aus
und mache dieselbe Operation (int Argument einführen),
was wird dann neu compiliert:
foo1.c
foo2.c
main.c
foo1.c wird völlig sinnlos neu compiliert.
Bei ein paar mehr *.c Files fängt das an, ins Gewicht zu fallen,
weil auf diese Art immer alle *.c neu compiliert werden.
Jede Änderung in irgendeinem Header führt dazu, dass defs.h
für make als veraltet gilt, und da alle *.c von defs.h abhängen,
wird alles neu compiliert. Super.
Disclaimer: Wie bereits gesagt, bei Libraries macht ein
'Über-Include' sehr wohl Sinn. Allerdings: Libraries ändern
sich nicht sehr häufig, so dass das verschmerzbar ist, wenn
die Maschine beim build rumrödelt.
Das gilt aber nicht für normalen Source Code.
> Ich bin der Entwickler von CubicIDE, einer führenden C/C++> Entwicklungsumgebung für Amiga/MorphOS Computer, Umfang ca 300 MB,> Sourecode der Kern-IDE ca 8 MB (im Moment ist die Webseite leider> offline, Server-Problem). Ich habe vermutlich mehr Code geschrieben, als> alle Leute in diesem Thread zusammen :)
Ich persönlich bin ja ein Freund/Verfechter der Qualität, nicht der
Quantität. Aber das soll Dich abhalten mehr Code zu produzieren. ;-)
Im Rahmen des Forums, in dem wir hier diskutieren, sollten wir
vielleicht nicht Schwa... äh, Codegrößen vergleichen, sondern dem OP
sagen, wie man es sinnvoll machen kann. Da in so einen ATMega64
definitiv nicht mehr als 64 kByte Code reinpassen, kann ein Projekt in
jedem Fall übersetzt werden, ohne dass man Kaffee holen muss.
Ich persönlich fange typischerweise auch erst mal mit einem Modul an,
und wenn das Projekt umfangreicher wird, wird halt aufgeteilt in mehrere
C-Module, die ggf. die notwendigen Header exportieren. Letztlich ergibt
sich beispielsweise für das main-Modul kein eigener Header. Und ja, auch
ich fasse alle Header in einer "defs.h" zusammen, weil's übersichtlich
ist.
> Ich persönlich bin ja ein Freund/Verfechter der Qualität, nicht der
Quantität
Das schliesst sich nur für Anfänger gegenseitig aus. Qualität in kleiner
Menge erzeugen könne viele. Qualität in sehr grosser Menge zu
produzieren ist das Ziel. Meine Webseite ist inzischen wieder online,
dort kannst Du dir ein Bild von der Qualität meiner Arbeit machen
(http://devplex.awardspace.biz).
Zum Thema globale Header-Datei: wenn man einen faltenden Editor
verwendet, dann werden lange Dateien zu kurzen Dateien. Man sieht selten
mehr als ein paar Zeilen: Wenn ich die Strukturen sehen will, klappe ich
den Block mit den Strukturen auf. Wenn ich eine bestimmte Struktur
suche, zeigt mir der Editor auf Knopfdruck eine Liste aller Elemente
(Strukturen usw.) im Text an und ich kann sie dort auswählen. Dadurch,
dass alles in einer Datei ist, ist alles blitzschnell anspringbar. Kein
Wühlen durch zwanzig Header mit jeweils 8 Zeilen, garniert mit
ellenlangen, hohlen Kommentaren. Der andere Vorteil einer zentralen
Datei ist, dass Macros, Strukturen usw. garantiert konsistent über das
ganze Projekt sind und dass Prototypen und globale Variablen überall
zugriffsbereit sind. Man kommt nicht in die Versuchung, für jeden
Teilbereich etwas Neues zu erfinden.
Meine defs.h-Datei ist üblicherweise so aufgebaut: Compiler-spezifische
Definitionen. Einbinden der System-Includes und der lokalen
Include-Dateien (es gibt natürlich mehr als eine Header-Datei im
Projekt, z.B. für Ressourcen wie Strings, aber nicht eine Header-Datei
pro Quelltext). Definition der Macros. Definition/Enumeration der
Konstanten. Definition der Strukturen. Definition der globalen
Variablen. Funktions-Prototypen aller Module - wird automatisch
aktualisiert. Alle diese Blöcke sind sinnvoll gefaltet: nach dem Laden
der defs.h sehe ich etwa 10 Zeilen. Und zwar sinnvolle Zeilen
("Strukturen", "Definitionen", "Globals") und kein Murks wie lange
Dateiköpfe. Hinter diesen 10 Zeilen verbergen sich im Fall von Cubic IDE
3800 Zeilen oder 160 KB. Durch einen guten Editor merkt man davon
nichts: jeder Struktur, Konstante usw. ist in Sekunden anspringbar -
meistens mit drei bis vier Tastatureingaben.
Der erwähnte Aufbau ist natürlich nicht dogmatisch zu sehen. Konstanten,
die zu Strukturen gehören, definiere ich beispielsweise in deren Nähe.
>Zum Thema globale Header-Datei: wenn man einen faltenden Editor>verwendet,
(Rest der Werbung für eine bestimmte IDE gelöscht)
Ich habe ja nun auch schon einige Zeilen Code geschrieben, aber einen
faltenden Editor habe ich noch nie vermisst. Eine IDE, die den schnellen
Zugriff auf alle Projektdateien ermöglicht, ist ja prima. Eine
source-Datei, die nur "zusammengefaltet" verständlich wird, ist Murks.
Aber das ist Geschmacksache.
Oliver
Ich verwende i.d.R. nur einen Header. Allerdings lege ich Wert darauf,
z.B. die Prototypen nach zugehörigen c-Dateien zu ordnen (+ Kommentar).
Funktionen die aus anderen Modulen aufgerufen werden werden als extern
deklariert, Funktionen die nicht geshared werden bekommen einen
dementsprechenden Kommentar mit sachdienlichen Hinweisen.
Globale Variablen werden grob geordnet und bekommen einen Kommentar in
welchem Modul sie initialisiert/hauptsächlich benutzt werden.
Wenn man allerdings so wie Karl eine Stunde compilieren muss, dann
sollte man sich nochmal Gedanken machen ob es anders nicht sinnvoller
wäre. Letztendlich ist das aber alles Geschmackssache.
> (Rest der Werbung für eine bestimmte IDE gelöscht)
Himmelherrgott, das war keine Werbung. Als ob nur mein Editor falten
könnte. Falten ist eine enorm nützliche Funktion, um den Überblick zu
erhöhen, und wer darauf verzichtet, gehört bestraft.
http://en.wikipedia.org/wiki/Folding_editor
>> es ließen sich ja auch>> alle c-files (z.b. in einer lib.c) includieren. ist aber nicht sehr>Also fuer die Behauptung solltest du jetzt aber nochmal eine Erklaerung>liefern.
ich sagte es ist möglich. und ich denke unter gewissen umständen macht
das evtl. sinn, z.b. wenn die sourcen innerhalb eines netzwerkes sind
und viele leute darauf zugreifen/daran entwickeln, ist es evtl. (!)
schneller das sich der compiler, der lokal auf dem rechner installiert
ist sich erst alle c-dateien holt und nur eine datei compiliert, als zig
oder 100'te dateien einzeln (übers netzwerk) zu compilieren.
das argument das sich bei einer übergeordneten headerdatei (egal ob
diese alle typen, prototypes in sich hat und es sonst keine weitere mehr
gibt [bin ich allerdings auch kein fan von], oder "nur" weitere header
dateien includiert werden) das projekt bei jeder kleinen änderung neu
compiliert wird ok, aber wenns nicht allzugroße projekte sind ist diese
lösung denke ich vor allem übersichtlicher.
gruß
rene
>es ließen sich ja auch>alle c-files (z.b. in einer lib.c) includieren.>wenn die sourcen innerhalb eines netzwerkes sind und viele leute darauf >zugreifen/daran entwickeln,
Wenn in solch einem Fall keine Versionverwaltung wie CVS und Nachfolger
zum Einsatz kommt, dürfte da nach spätestens zwei Tagen nichts
kompilierfähiges mehr vorhanden sein, und das in 256 Versionen.
Das wird nicht nur Murks, das wird Multiuser-Murks.
Oliver
Meine Meinung:
Gerade Anfängern sollte man auch im Hinblick auf ihren
späteren Werdegang die Dinge vernünftig beibringen.
Klar habt ihr recht, dass auf einem AVR mit den typisch
relativ kleinen Codegrößen man das auch anders machen kann.
ABer zuerst soll er doch bitte mal lernen, wie man das
vernünftig macht, bevor man ihm die quick&dirty Variante
zeigt.
Wozu Einrückungen? Meine 20 Zeilen kann ich auch so überblicken.
Wozu sprechende Variablennamen? Einbuchstabige tippen sich viel
schneller und meine 10 Variablen kann ich auch so auseinanderhalten.
Und dann kriegst du so einen in dein Team und must ihm erst
mal Coding-Standards und Projektmanagement beibringen, obwohl
er nach eigenen Aussagen schon 'seit Jahren C programmiert'.
Und Dietmar: Das ganze hat nichts mit einer IDE oder den
Fähigkeiten eines Editors zu tun. Apropos: Eine gute IDE
unterstützt eine Codesuche. Da stelle ich den Cursor auf
die Variable oder den Datentyp oder die Funktion von der
ich Informationen brauche, drücke eine Taste und der Editor
sucht mir das File und die Stelle wo das Zeugs definiert ist.
Das reicht im Regelfall völlig aus um auch in großen Projekten
nicht den Überblick zu verlieren.
Auf jeden Fall Headerfiles benutzen, und idealerweise zu jeder Source
einen Header.
Die Sache hat, mal abgesehen davon, dass man damit den Code in logische
Einheiten aufteilen kann und neukompilieren deutlich schneller geht, den
Vorteil, dass man zwangsweise ein paar mehr Überlegungen zur
Programmstruktur anstellt.
Normalerweise sollte man das zwar vorher machen, aber je kleiner die
Projekte... also wenn man sich für einen neuen Funktionsblock erstmal im
Header alle globalen Funktionen definiert die man dafür braucht und
dabei mal kurz drüber nachdenkt wie das dann später funktionieren soll,
hat man das Interface schonmal durchdacht, und Fehler fallen dann
schnell auf.
Außerdem kann man sich dann aussuchen in welcher Reihenfolge man den
Code schreibt (bzw. wenn mehrere Leute dran schreiben kann gleichzeitig
programmiert werden), weil die Funktionen schon spezifiziert sind. Der
eine schreibt implementiert dann zB. die Funktionen, der andere schreibt
schon an der Routine, die die Funktionen verwenden soll.
PS: IDE -> offene Konsole + mehrere KWrite Instanzen auf verschiedene
Desktops verteilt.
Der Programmierer macht den Unterschied, nicht die IDE.