Registriert: Mo Nov 08, 2010 18:41 Beiträge: 769
Programmiersprache: Gestern
OpenglerF hat geschrieben:
Der Compiler kann nichts dafür, wenn er Änderungen nicht bemerkt. Das muss ein Fehler im Buildsystem(zb. diesen "Make"-Kram) sein, das bei Code::Blocks vielleicht auch irgendwie mit der IDE verknüpft ist. Ich hatte dieses Problem bisher auch mit Code::Blocks noch nicht, obwohl ich sonst Visual Studio verwende, das vom verwöhnen bei der Benutzung auf der Windows-Platform meiner Meinung nach ganz vorne liegt. Insbesondere wenn du dich eh auf Windows beschränken willst und scheinbar WinAPI nutzt, würde ich auch Visual Studio verwenden.
Die Trennung von Headern und Sources ist in der Tat nicht gerade das Gelbe vom Ei. Neben das es einfach unpraktisch ist führt es auch zu weiteren Problemen, zb. verlängert es die Compilezeiten erheblich. Es gibt schon seit längerer Zeit die Idee so genannte "Module" in C++ zu integrieren. Leider hat das der Standard bisscher nicht geschafft umzusetzen. Frühestens in C++17 wäre mit so einer Neuerung zu rechnen...
Das von dir erähnte positive gibt es übrigens auch schon in C und hat nichts mit C++11 zu tun.
GCC erzeugt Abhängigkeiten nur für make (vorausgesetzt man compeliert mit entsprechenden Flags). Code::Blocks soll auch irgendwie makefiles automatisch erzeugen und ausführen können, frag mich aber nicht wie das geht
Aha. Sieht ja drollig aus. Aber dafür ist die Windowskonsole eben eindeutig nicht gedacht. Die Konsole ist die Standardausgabe in C/C++ die man normalerweise als einfache Möglichkeit zur Ausgabe von Log-Meldungen verwendet. Menüs in der Konsole dafür sind eigentlich spätestens seit dem Ende von MSDOS nicht mehr zeitgemäß. Nomalerweise solltest du wenn du eine Grafikanwendung mit OpenGL/Dx schreibst, die Menüs natürlich dort mit der GPU zeichnen. Es gibt auch fertige Lib. FLTK sollte das zum Beispiel können. Und besonders wenn es mehr in die Anwendungsrichtung mit vielen GUI Funktionen und so weiter geht, kannst du ja auch "richtige" Fenster aufmachen mit "normalen" Menüs. Zb mit der WinAPI(die etwas komplex zu verwenden ist) oder besser einen fertigen auch platformunabhänigen Lib wie zb. wxwidgets.
Registriert: Mo Nov 08, 2010 18:41 Beiträge: 769
Programmiersprache: Gestern
Für coole Grafiken in der Konsole unter Windows ist das Zauberwort WriteConsoleOutput. Damit kannst du sehr bequem Blitobjekte erstellen und so alles mögliche zaubern. Schau dir einfach mal den Beispiel-Link weiter unten an, da haste alles fertig zum Copy & Paste
Registriert: Mi Aug 14, 2013 21:17 Beiträge: 588
Programmiersprache: C++
mathias hat geschrieben:
Warscheinlich bin ich von Free-Pascal verwöhnt, wen ich in einer Unit etwas ändere, so merkt der Kompiler dies. Der gcc merkt dies nicht. Vieleicht liegt dies auch an Code::Blocks.
Speicherst du die Datei, an der du was geändert hast, vor dem kompilieren? Wenn ja, dann sollte der gcc das merken. Bei Delphi ist das Speichern afair nicht nötig, da die IDE dem Compiler nötigenfalls den ungespeicherten Code aus dem Editor übergibt.
_________________ So aktivierst du Syntaxhighlighting im Forum: [code=pascal ][/code], [code=cpp ][/code], [code=java ][/code] oder [code=glsl ][/code] (ohne die Leerzeichen)
Registriert: Do Sep 02, 2004 19:42 Beiträge: 4158
Programmiersprache: FreePascal, C++
Der Compiler macht auf keine Art und Weise Dependency-Tracking. Wie auch. Entweder er wird für eine C-Datei aufgerufen und baut diese neu, oder halt nicht. Das ist Sache des Buildskripts (in welcher Form auch immer das vorliegt). Nur damit wir hier mal die Begriffe klar bekommen. GCC ist ein Compiler, und macht kein Dependency-Tracking. Code::Blocks ist eine IDE, inwiefern die den Buildprozess kontrolliert, weiß ich nicht (ob die z.B. eine CMakeLists.txt anlegt und cmake benutzt oder ob die ein Makefile anlegen oder ob sie’s ganz selber machen etc.).
grüße, Horazont
_________________ If you find any deadlinks, please send me a notification – Wenn du tote Links findest, sende mir eine Benachrichtigung. current projects: ManiacLab; aioxmpp zombofant network • my photostream „Writing code is like writing poetry“ - source unknown
„Give a man a fish, and you feed him for a day. Teach a man to fish and you feed him for a lifetime. “ ~ A Chinese Proverb
Registriert: Mo Nov 08, 2010 18:41 Beiträge: 769
Programmiersprache: Gestern
Das speichern nuetzt dir ja wie gesagt nix. Die Header Dateien sind erst einmal kein Quellcode. Der Preprozessor ersetzt lediglich das include durch den Inhalt der Header. Erst wenn das in einer Quellcode-Datei passiert wird der Inhalt einer Header-Datei auch zu Quellcode. Man kann die Header also speichern bis man schwarz wird, solange der Preprozessor nicht ueber eine Quellcode-Datei geht entsteht auch kein neuer Quellcode. Wenn man mal beim gcc mit der Option -E compeliert kann man das wunderbar sehen.
Die meisten Compiler generieren daher extra Dependency-Informationen. Wenn man das beim GCC einschaltet werden zusaetzlich noch extra Dateien erzeugt. Diese sehen dann zum Beispiel wie folgt aus:
Code:
build/Debug/GNU-MacOSX/main.o: main.cpp shared.h
shared.h:
Das Build System kann so erkennen das fuer die Objekt-Datei "main.o" die Datei "main.cpp" und zusaetzlich die Datei "shared.h" benoetigt werden. Wenn man jetzt das Dependency-Checking im Build-System aktiviert dann erkennt das Build-System das nicht nur "main.cpp" auf Aenderungen geprueft werden muss. Das sieht dann zum Beispiel bei make wie folgt aus:
Code:
# Enable dependency checking
.dep.inc: .depcheck-impl
include .dep.inc
Die meisten IDE's machen diese Schritte als Default-Optionen. DevCpp zum Beispiel macht dies aber nicht automatisch und hat auch keine Optionen dafuer. Daher gibt es in solchen Faellen, wenn du nicht gerade absoluten Schrott benutzt, eine Option um eigenen Makefiles zu benutzen.
Der Hintergrund fuer dieses System ist eigentlich ziemlich Simpel. C-Module sind sehr kompliziert zu verarbeiten (bei C++ noch schlimmer), daher gibt es keine extra Befehle um ganze Module einzubauen. Stattdessen muss man jede Komponente die man aus einen anderen Modul haben will extra definieren. Wenn man nun diese Definitionen in eine extra Datei auslagert kann man ueber das Include das Ganze zentral verwalten und muss nicht immer wieder tausende von Zeilen von Code fuer Aenderungen editieren. Wenn man so will ist das Ganze eigentlich nichts anderes als ein Interface bei Java, nur eben cooler. Man kann naemlich auch tatsaechliche Funktionalitaet so auslagern. Wenn du zum Beispiel eine Variable im Header erzeugt:
Code:
static char x = 'a';
Dann erzeugst du fuer jedes Include eine neue Variable (!!!Achtung!!! das fuehrt haeufig zu Redefinitionen). Ein klassischer Anwendungsfall fuer sowas ist zum Beispiel die Regionale Speicher-Verwaltung.
Code:
void fun(void) {
#include(BEGIN_REGION) //ein neue Region wird auf dem Stack erzeugt
... //der dynamische Speicher landet in der Region
} //die Region wird automatisch freigegeben, und somit der dynamische Speicher, wenn die Funktion verlassen wird
Registriert: Di Mai 18, 2004 16:45 Beiträge: 2622 Wohnort: Berlin
Programmiersprache: Go, C/C++
Der Ursprüngliche Grund für die Trennung in Header und Module hatte den Grund, dass man kompilierten Code weiter geben wollte und das Funktioniert, wenn man den Header und die *.a files aus liefert. Header und Module zusammen zu matschen, wie es bei C# und Java ist, hat viele Hürden zu meistern. Das erste Problem wären Templates, man müsste Templates in jedem Module neu bauen und in dem Modul, wo es deklariert wird darf es nicht gebaut werden. Bibliotheken wie Boost wären dann absout unnutzbar, weil das Kompilieren so extrem langsam wäre, weil erstmal einige hundert Templates pro Module durch bauen. Man müsste nun im Modul, wo das Template existiert Templates spezialisieren und dann ist das Modul nicht nur unsagbar groß sondern baut unmengen an Dependencies auf, das beschleunigt die nutzung für die spezialisierten Fälle aber macht das entsprechenden Modul langsam. Es würde arge Probleme mit namespace Kollisionen geben, wenn ein Modul in den Header verschmilzt und global definiert variablen/funktionen verwendet. Da sind auch noch viel schlimmere Fallstricke und ich persönlich finde es auch nicht als Vorteil, wenn man Header und Modul in ein Modul zusammen packt. Man kann dies mit einer Strikten Coding Guideline und speziellen guard makros machen aber der Code ist super unleserlich :\
_________________ "Wer die Freiheit aufgibt um Sicherheit zu gewinnen, der wird am Ende beides verlieren" Benjamin Franklin
Der Ursprüngliche Grund für die Trennung in Header und Module hatte den Grund, dass man kompilierten Code weiter geben wollte und das Funktioniert, wenn man den Header und die *.a files aus liefert. Header und Module zusammen zu matschen, wie es bei C# und Java ist, hat viele Hürden zu meistern.
Registriert: Do Sep 02, 2004 19:42 Beiträge: 4158
Programmiersprache: FreePascal, C++
„Ohne Probleme“. Ein Problem ist z.B., dass es keine Menschenlesbare Form des Interfaces gibt. Bei C/C++ kann man immer in die Header reinschauen, wenn du bei Delphi nur ne DCU oder bei Pascal nur eine PPU hast, haste verloren.
grüße,
_________________ If you find any deadlinks, please send me a notification – Wenn du tote Links findest, sende mir eine Benachrichtigung. current projects: ManiacLab; aioxmpp zombofant network • my photostream „Writing code is like writing poetry“ - source unknown
„Give a man a fish, and you feed him for a day. Teach a man to fish and you feed him for a lifetime. “ ~ A Chinese Proverb
Bei C/C++ kann man immer in die Header reinschauen, wenn du bei Delphi nur ne DCU oder bei Pascal nur eine PPU hast, haste verloren.
Wen jemmand den Quellcode nicht rausgeben will, dann muss er halt für eine ordentliche Dokumetation der Unit machen. Bis jetzt habe ich es ganz selten erlebt, das ich den Quell-Code nicht hatte.
Registriert: Di Mai 18, 2004 16:45 Beiträge: 2622 Wohnort: Berlin
Programmiersprache: Go, C/C++
mathias hat geschrieben:
Zitat:
Bei C/C++ kann man immer in die Header reinschauen, wenn du bei Delphi nur ne DCU oder bei Pascal nur eine PPU hast, haste verloren.
Wen jemmand den Quellcode nicht rausgeben will, dann muss er halt für eine ordentliche Dokumetation der Unit machen. Bis jetzt habe ich es ganz selten erlebt, das ich den Quell-Code nicht hatte.
Vieleicht Branchen bedingt, in der Spieleindustrie bekommst du prinzipiell nur ein Paket von lib/a files und den Headern und für den Code zahlt man dann entsprechend dem Projekt Budget wesentlich mehr, als die fix kosten für precompiled Code. Daher bin ich auch sehr Glücklich, dass dies geht, ob ich nun 1.500€ oder 800.000-1.000.000€ zahle macht dann schon ein Unterschied. Selbst einfache Middleware kostet schon ein gutes Jahresgehalt eines Programmierer, wenn man den Source dazu haben will.
mathias hat geschrieben:
Zitat:
Der Ursprüngliche Grund für die Trennung in Header und Module hatte den Grund, dass man kompilierten Code weiter geben wollte und das Funktioniert, wenn man den Header und die *.a files aus liefert. Header und Module zusammen zu matschen, wie es bei C# und Java ist, hat viele Hürden zu meistern.
Wieso geht dies bei Pascal ohne Probleme ?
Gegenfrage. Wieso gehen Templates nicht in Java ? Wenn die Frage beantworten kannst, dann hast auch die Antwort für deine Frage.
OpenglerF hat geschrieben:
Zitat:
Der Ursprüngliche Grund für die Trennung in Header und Module
Wie meinst du das? Aktuell gibt es keine Module in C++.
*.cpp, *.c, *.c++ sind Module.
_________________ "Wer die Freiheit aufgibt um Sicherheit zu gewinnen, der wird am Ende beides verlieren" Benjamin Franklin
Mitglieder in diesem Forum: Google [Bot] und 29 Gäste
Du darfst keine neuen Themen in diesem Forum erstellen. Du darfst keine Antworten zu Themen in diesem Forum erstellen. Du darfst deine Beiträge in diesem Forum nicht ändern. Du darfst deine Beiträge in diesem Forum nicht löschen. Du darfst keine Dateianhänge in diesem Forum erstellen.