DEUTSCHE VERSION |
|
Links | | | Forums | | | Comments | | | Report news |
Chat | | | Polls | | | Newsticker | | | Archive |
amiga-news.de Forum > Programmierung > C-Anfängerkurs | [ - Search - New posts - Register - Login - ] |
1 2 3 4 -5- | [ - Post reply - ] |
2004-04-01, 12:34 h whose Posts: 2156 User |
Zitat: Damit hängts meistens weniger zusammen. Mehr mit dem Tohuwabohu in den Includes. Wennst ne Standard-StormC4-Installation frisch von der CD zum compilieren benutzt, kanns Dir passieren, daß der GCC wegen z.B. Printf() (die AOS-Funktion!) mit "parse error" meckert, obwohl Du <proto/dos.h> eingebunden hast. Das kommt _nicht_ daher, weil er die Strukturen nicht gesehen hat, sondern daher, daß das Einsprung-Macro ganz einfach falsch ist Im übrigen tendieren diese Macros dazu, den Namespace zu überschwemmen, daher kommt auch der Fehler mit #include <clib/dos_protos.h>. Regel ist: Aufruf der OS-Funktionen via Stubs aus der Compiler-Bibliothek: #include <clib/...> Aufruf der OS-Funktionen via #pragma oder Macro: #include <proto/..> Tip an Mad Dog: Setz mal in den StormC4-Compiler-Optionen ein zusätzliches #define ein: NO_INLINE_LIBCALLS (keine OS-Einsprünge via inline-Macros) Das dürfte den Fehler beseitigen und sollte bei ner "normalen" GCC-Installation auch funktionieren. Grüße [ - Answer - Quote - Direct link - ] |
2004-04-01, 14:17 h gni Posts: 1106 User |
Zitat:Nein. Zitat:Richtig. Zitat:Wenn die normale GCC Installation andere Header verwendet, funktioniert das nicht. [ - Answer - Quote - Direct link - ] |
2004-04-02, 16:23 h Mad_Dog Posts: 1944 User |
So. Ich habe das Sierpinski-Fraktal aus Kapitel 8 jetzt mal gcc-tauglich gemacht:code:/* Sirpinski-Fraktal * */ #include <exec/types.h> #include <exec/exec.h> #include <intuition/intuition.h> #include <graphics/gfx.h> #include <dos/dos.h> #include <stdlib.h> #include <clib/intuition_protos.h> #include <clib/graphics_protos.h> #include <clib/exec_protos.h> /* Makro zur Erzeugung einer Zufallszahl * im Bereich min..max */ #define random(min,max) ((rand() % (int)((max+1.0)-min))+min) // Symbolische Konstanten #define WIDTH 400 // Breite des Fensters #define HEIGHT 300 // Höhe des Fensters struct Window *Fenster; // Zeiger auf Window-Struktur struct Library *IntuitionBase; // Zeiger auf IntuitionBase-Struktur struct Library *GfxBase; // Zeiger auf Library-Struktur struct RastPort *rp; // Zeiger auf RastPort-Struktur // Funktionsprototypen void DrawSierpinski(void); int main(void) { // Intuition Library öffnen IntuitionBase = OpenLibrary("intuition.library",36L); if (IntuitionBase != NULL) { // Graphics Library öffnen GfxBase = OpenLibrary("graphics.library",0L); // Fenster mittels Tags öffnen Fenster = OpenWindowTags(NULL, WA_Left, 100, // Abstand vom linken Rand WA_Top, 100, // Abstand vom oberen Rand WA_Width, WIDTH, // Breite WA_Height, HEIGHT, // Höhe WA_Title, "Sierpinski", // Fenstertitel WA_ScreenTitle, "Sierpinski", // Screen-Titel WA_CloseGadget, TRUE, // Close-Gadget WA_DragBar, TRUE, // Ziehleiste WA_DepthGadget, TRUE, // Depth-Gadget WA_GimmeZeroZero, TRUE, // Ursprung 0/0 WA_IDCMP, IDCMP_CLOSEWINDOW, WA_Activate, TRUE, // Fenster aktivieren TAG_DONE); if (Fenster != NULL) { rp = Fenster->RPort; // rp zeigt auf RastPort des Fensters SetRast(rp, 1L); // Fensterinhalt löschen SetAPen(rp, 2L); // Farbe setzen DrawSierpinski(); // Fraktal zeichnen // Auf Close-Gadget warten Wait(1L << Fenster->UserPort->mp_SigBit); CloseWindow(Fenster); // Fenster schließen } // end if } // end if // Libraries schließen if (GfxBase != NULL) CloseLibrary(GfxBase); if (IntuitionBase != NULL) CloseLibrary(IntuitionBase); return 0; } // Funktion zum Zeichnen des Sirpinski-Fraktals void DrawSierpinski(void) { int iterate; SHORT x1, y1, x2, y2; x1 = x2 = WIDTH/2; y1 = y2 = 0; // Schleife zum Iterieren und Zeichnen der Pixel for(iterate = 0; iterate < 10000; iterate++) { // Zufallswerte erzeugen/ switch (random(0,2)) { case 0: x1 = (x2 + WIDTH/2) / 2; y1 = y2 / 2; break; case 1: x1 = x2 / 2; y1 = (y2 + HEIGHT) / 2; break; case 2: x1 = (x2 + WIDTH) / 2; y1 = (y2 + HEIGHT) / 2; break; } // Amiga Graphik-Primitive WritePixel (rp,x1, y1); x2 = x1; y2 = y1; } } Dabei habe ich folgendes festgestellt: 1.) Der gcc mag nur Zeiger auf Library-Structs, die genauso heißen wie der Datentyp des Structs selbst, also z.B. struct Library *IntuitionBase; StormC hingegen schluckt auch sowas wie struct Library *IntBase; . Dabei finde ich es von Stil her schöner, wenn der Zeiger nicht unbedingt den gleichen Bezeichner hat, wie der Typ des Structs. 2.) Das geschilderte Problem mit dem Syntax Error kommt, daher, daß es der gcc einem übel nimmt, wenn man bei einem Typecast den Datentyp nicht in Klammern setzt. StormC ist es egal. Deshalb hat mein Makro random() auch nicht funktioniert. 3.) Der gcc gibt Warnings bezüglich der Header-Datei <clib/graphics_protos.h> aus. (bin etwas ratlos - flasche Includes?) -- http://www.norman-interactive.com [ - Answer - Quote - Direct link - ] |
2004-04-02, 17:01 h gni Posts: 1106 User |
Zitat:Die proto/ Header sind IMHO besser, aber clib/ geht natürlich auch. Das vermeidet das Problem der inkompatiblen Librarytypen... Zitat:Wie hier. "Richtig" ist "struct IntuionBase *" bzw "struct GfxBase *".code:struct Library *IntuitionBase; // Zeiger auf IntuitionBase-Struktur struct Library *GfxBase; // Zeiger auf Library-Struktur "struct Library *" geht halt nicht, wenn man die proto/ Header die "richtigen" Typen verwenden. Zitat:GCC schluckt auch IntBase. Dann passiert aber was anderes als Du denkst. Wenn Du nicht selber das richtige Symbol belegst dann macht der Compiler das für dich... Zitat:Storm Fehler. Frag mal Solar bezüglich seinen Erfahrungen mit Storm und seinen SFStools. Zitat:GCC wird schon seinen Grund haben, zu meckern. [ - Answer - Quote - Direct link - ] |
2004-04-02, 17:22 h Mad_Dog Posts: 1944 User |
Zitat: Seltsamerweise ist das in einigen Beispielen der NDKs auch mit struct Library *IntuitionBase; gelöst. Jedenfalls kann man sich so die lästigen Typecasts sparen. Aber korrekt wäre wohl: code:... struct IntuitionBase *IntuitionBase; // Zeiger auf IntuitionBase-Struktur struct GfxBase *GfxBase; // Zeiger auf GfxBase-Struktur ... // Intuition Library öffnen IntuitionBase = (struct IntuitionBase *) OpenLibrary("intuition.library",36L); if (IntuitionBase != NULL) { // Graphics Library öffnen GfxBase = (struct GfxBase *) OpenLibrary("graphics.library",0L); ... // Libraries schließen if (GfxBase != NULL) CloseLibrary((struct Library *)GfxBase); if (IntuitionBase != NULL) CloseLibrary((struct Library *)IntuitionBase); ... -- http://www.norman-interactive.com [ - Answer - Quote - Direct link - ] |
2004-04-02, 17:29 h Mad_Dog Posts: 1944 User |
Übrigens: Es muß Sierpinski heißen. -- http://www.norman-interactive.com [ - Answer - Quote - Direct link - ] |
2004-04-02, 18:02 h Solar Posts: 3680 User |
Zitat: Öhm... ich glaube Du verwechselst mich mit jemandem. SFS habe ich nie genutzt, geschweige den compiliert. [ - Answer - Quote - Direct link - ] |
2004-04-02, 18:15 h Mad_Dog Posts: 1944 User |
Jedenfalls hab ich die Codes auf der Website der C-Kurses jetzt entsprechend geändert. Falls es noch Unstimmigkeiten geben sollte: Bitte Schreien! -- http://www.norman-interactive.com [ - Answer - Quote - Direct link - ] |
2004-04-02, 20:00 h Palgucker Posts: 1342 User |
@ Mad_dog Besten Dank dafür, das Du den Code noch mal unter die Lupe genommen hast. GCC kompiliert jetzt jedenfalls ohne zu murren. Wobei ich bisher Punkt 3 nicht nachvollziehen kann, obwohl ich auch nur die NDK_3.9 Include aus dem Netz verwende. mfg Palgucker [ - Answer - Quote - Direct link - ] |
2004-04-03, 01:37 h obw Posts: 94 User |
Zitat: Asche über mein Haupt! Bin ich entschuldigt, wenn ich sage, daß ich eigentlich immer die proto-Header verwende und völlig vergessen hatte, wofür die clib-Header eigentlich sind? *schäm und in die Ecke stell* OBW [ - Answer - Quote - Direct link - ] |
2004-04-03, 10:38 h Mad_Dog Posts: 1944 User |
Trotzdem kommt mir das ganze Rumgecaste noch reichlich sinnlos vor. Hier definiere ich den Zeiger namens IntuitionBase als einen Zeiger auf eine Struktur vom Typ IntuitionBase: code:struct Window *Fenster; // Zeiger auf Window-Struktur struct IntuitionBase *IntuitionBase; // Zeiger auf IntuitionBase-Struktur Dann muß ich einen Typecast machen, bevor ich den Zeiger zuweise, weil OpenLibrary einen Zeiger auf eine Struktur vom Typ Library zurückgibt: code:// Intuition Library öffnen IntuitionBase = (struct IntuitionBase *) OpenLibrary("intuition.library",36L); Beim Schließen muß ich nochmal Casten, da CloseLibrary als Eingabeparameter ebenfalls einen Zeiger auf eine Struktur vom Typ Library erwartet: code:// Librarie schließen if (IntuitionBase != NULL) CloseLibrary((struct Library *)IntuitionBase); Ich halte also einen Zeiger auf IntuitionBase, obwohl ich eigentlich einen Zeiger auf Library brauche. Ziemlich strange. Und daß der Zeiger tatsächlich IntuitionBase heißen muß, liegt an der Definition des globalen Zeigers IntuitionBase in <proto/intuition.h> : code:extern struct IntuitionBase * IntuitionBase; Für meinen Geschmack ein Bischen viel Kuddelmuddel. Mir scheint, der gcc will auf Biegen und Brechen Lattice C kompatibel bleiben. Ich persönlich fand meinen ursprünglichen Code irgendwie schlüssiger... -- http://www.norman-interactive.com [ Dieser Beitrag wurde von Mad_Dog am 03.04.2004 editiert. ] [ - Answer - Quote - Direct link - ] |
2004-04-03, 13:34 h whose Posts: 2156 User |
Zitat: Mach Dir nichts draus. Es liegt schlicht und ergreifend daran, daß die struct IntuitionBase ein (winzig kleine) Erweiterung zur struct Library darstellt. Ist ähnlich wie mit der DosBase. Die AOS-Entwickler haben da dann vor einem Dilemma gestanden: struct Library so erweitern, daß die alle Eventualitäten abedeckt, oder lieber für einige wenige Libraries eine Sonderbehandlung vornehmen und dafür den Großteil der anderen Libraries gleichbehandeln. Sie haben letzteres getan, dafür muß man dann halt casten. Nicht schön, aber ist halt so. @gni: Deine Aversion für StormC sei Dir gelassen, aber erzähl nichts von Fehlern, wo keine Fehler sind. Mad_Dog hat ein Makro verwendet. StormC3 ist _nicht_ ANSI-C-Konform. Schau nach, was im AT&T-Draft zum Thema "Typecasts mit Macros" steht. Nochwas: Wenn ich von einer "normalen" GCC-Installation spreche, meine ich eine, deren Includes per fd2inline erzeugt wurden. Beim StormC4 wurden diese Includes eben mit ner älteren Version von fd2inline für den GCC erzeugt. Dabei enstehen fehlerhafte inline-Macros, die eben _doch_ den Namespace überschwemmen. Würdest Du den StormC4 kennen, wüßtest Du um dieses Problem. Grüße [ - Answer - Quote - Direct link - ] |
2004-04-03, 20:11 h Mad_Dog Posts: 1944 User |
Zitat: Jaja... aber es würde auch so gehen: code:struct Library *IntuitionBase; Und dann müsste ich nicht so sinnlos rumcasten. Aber einige von Euch schreien dann hell auf, obwohl es in den meisten NDK-Beispielen auch so gemacht ist... -- http://www.norman-interactive.com [ - Answer - Quote - Direct link - ] |
2004-04-04, 14:42 h Palgucker Posts: 1342 User |
@ Mad_Dog Habe heute nochmal an Deinen alten Sierpinski-Code zur Übung 'rumgebastelt, und musste erstaunt feststellen, das bei mir nur eine einzige Änderung von Nöten war, die über Gedeih oder Verderb entschied. Und zwar änderte ich nur #define random(min,max) ((rand() % int((max+1.0)-min))+min) in #define random(min,max) ((rand() % (int)((max+1.0)-min))+min) Und ab da konnte ich mit gcc selbst mit -Wall ohne jegliche Warnungen durchkompilieren. Wohlgemerkt, die anderen Aufrufe von struct Library *IntBase; bis ... if (IntBase != NULL) CloseLibrary(IntBase); wurden nicht geändert. VBCC war allerdings erst zufrieden, als der Code auch in dieser Hinsicht vollständig geändert wurde. Übrigens ist es mir als Anfänger ziemlich egal ob ich mir >>struct IntuitionBase *IntuitionBase;<< statt >>struct Library *IntBase;<< und >>IntuitionBase = (struct IntuitionBase *) OpenLibrary("intuition.library",36L);<< statt >>IntBase = (OpenLibrary("intuition.library",36L));<< usw. angewöhne, da ich mich nicht umstellen muss. Wenn der Quelltext sich dann aber auf 3 Compilern übersetzen lässt, anstatt nur auf einem, dann empfinde ich das als grossen Vorteil. mfg Palgucker [ Dieser Beitrag wurde von Palgucker am 04.04.2004 editiert. ] [ - Answer - Quote - Direct link - ] |
2004-04-04, 19:10 h Mad_Dog Posts: 1944 User |
Zitat: Ich muß zugeben, daß ich das Makro aus Faulheit aus einem alten Code herauskopiert habe. Die Typumwandlung kann man sich bei diesem Beispiel auch sparen: code:--#define random(min,max) ((rand() % ((max+1)-min))+min) http://www.norman-interactive.com [ - Answer - Quote - Direct link - ] |
2004-04-05, 11:48 h gni Posts: 1106 User |
Zitat:Na sowas, Helios != Solar. [ - Answer - Quote - Direct link - ] |
2004-04-05, 11:54 h gni Posts: 1106 User |
Zitat:Es steht nirgends, das das NDK ohne Fehler ist ;) Die Type-Probleme entstehen erst, wenn man die proto/ Header verwendet. Ursprünglich waren die NDK Beispiele nur für SAS/C und verwendeten clib+pragmas ohne "extern base" (wurde da nicht benötigt). [ - Answer - Quote - Direct link - ] |
2004-04-05, 12:18 h Solar Posts: 3680 User |
Zitat: true. [ - Answer - Quote - Direct link - ] |
2004-04-05, 12:24 h gni Posts: 1106 User |
Zitat:Ganz ohne Casts gehts nicht, wenn man die "richtgen" Typen verwenden will und auf globale Librarybasen steht. Bei lokalen Librarbasen als Funktionsargument oder in Strukturen, ist der Typ belanglos. Es sollte natürlich ein zu "struct Library *" kompatibler Type sein, zb. APTR. Wenn man C++ nutzt muß man dann aber auch casten bei OpenLibrary. Zitat:Der muß sein. Zitat:Der _muß_ nicht sein. Hier sollte man folgendes benutzen: code:Dann stimmt plötzlich der Type ohne Cast... Ups.&IntuitionBase->LibNode Zitat:Überhaupt nicht. Falls es Dir noch nicht aufgefallen ist, das ganze ist objektorientiert. Intuition hat eine "erweiterte" Librarybasis. Zitat:Da könnte auch APTR bzw. "struct Library *" stehen. Aber in dem Fall kommst Du nicht mehr _ohne_ Cast an die speziellen Felder von IntuitionBase wenn das mal benötigt werden sollte. Zitat:Das hat damit _nichts_ zu tun. Mir scheint eher, das zuwenig über den Sinn und Zweck von Casts nachgedacht wird. Viel zu oft werden Casts ohne Nachzudenken benutzt, um Warnungen loszuwerden. Zitat:Dann verwende keine proto/ Header und gut. [ - Answer - Quote - Direct link - ] |
2004-04-05, 13:02 h gni Posts: 1106 User |
Zitat:"IntBase" ist dem Compiler völlig egal. [ - Answer - Quote - Direct link - ] |
2004-04-05, 14:11 h Mad_Dog Posts: 1944 User |
Zitat: Wobei in die proto-Header laut Kommentar ursprünglich für Lattice C gedacht waren. -- http://www.norman-interactive.com [ - Answer - Quote - Direct link - ] |
2004-04-05, 14:14 h Mad_Dog Posts: 1944 User |
Zitat: Da gab's aber auch so Schlaumeier, die behauptet haben, der Zeiger müsse zwingend *IntuitionBase heißen, weil in proto/intuition.h ein solcher als globaler Zeiger deklariert ist... -- http://www.norman-interactive.com [ Dieser Beitrag wurde von Mad_Dog am 05.04.2004 editiert. ] [ - Answer - Quote - Direct link - ] |
2004-04-05, 17:25 h gni Posts: 1106 User |
Zitat:Stimmt, Lattice/SAS habe diese Header erfunden. AFAIK, um die Benutzung von clib+pragmas zu vereinfachen. Eventuell haben sie auch daran gedacht, Unterschiede zwischen Compilern zu verstecken. Fakt bleibt, mit den proto/ Header ist es vollkommen irrelevant wie die spezielen Header eines Compilers heissen. Alle Arbeit wird im proto/ Header gemacht. [ - Answer - Quote - Direct link - ] |
2004-04-05, 17:34 h gni Posts: 1106 User |
Zitat:Das widerspricht nicht meiner Aussage. Wieviel weisst Du über die AmigaOS Programmierung und wieviel von C? Der Typ der Variable "IntuitionBase" kann unter bestimmten Bedingungen varieren. Hauptsache es ist ein Zeiger und "passt" zu "struct Libary *". APTR ist so ein Typ. Der _Name_ der Basevariable ist in C _nicht_ egal. Der muß zwingend richtig sein oder es passiert was anderes als Du denkst. Das sich ein Programm trotz falscher Librarybasisname richtig verhält, liegt am automatischen Öffnen von verwendeten Bibliotheken (geht meist nur für die Standardbibliotheken). [ - Answer - Quote - Direct link - ] |
2004-04-06, 14:17 h Mad_Dog Posts: 1944 User |
-- Doppelposting gelöscht -- [ Dieser Beitrag wurde von Mad_Dog am 06.04.2004 editiert. ] [ - Answer - Quote - Direct link - ] |
2004-04-06, 14:18 h Mad_Dog Posts: 1944 User |
Zitat: Das frage ich mich langsam auch. Nein, Spaß bei Seite. Es ging um den Namen der Zeigervariablen. Zitat: Schon klar. Es heißt ja auch "ein Zeiger auf etwas von einem bestimmten Datentyp". Falls noch jemand was an meinem C-Kurs auszusetzen hat, dann können wir das gerne hier ausdisskutieren. Konstruktive Kritik ist immer willkommen. -- http://www.norman-interactive.com [ Dieser Beitrag wurde von Mad_Dog am 06.04.2004 editiert. ] [ - Answer - Quote - Direct link - ] |
1 2 3 4 -5- | [ - Post reply - ] |
amiga-news.de Forum > Programmierung > C-Anfängerkurs | [ - Search - New posts - Register - Login - ] |
Masthead |
Privacy policy |
Netiquette |
Advertising |
Contact
Copyright © 1998-2024 by amiga-news.de - all rights reserved. |