![]() |
ENGLISH VERSION |
|
![]() |
Links | | | Forum | | | Kommentare | | | News melden |
![]() |
Chat | | | Umfragen | | | Newsticker | | | Archiv |
![]() |
amiga-news.de Forum > Programmierung > C-Anfängerkurs | [ - Suche - Neue Beiträge - Registrieren - Login - ] |
1 2 3 4 -5- | [ - Beitrag schreiben - ] |
01.04.2004, 12:34 Uhr whose Posts: 2156 Nutzer |
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 [ - Antworten - Zitieren - Direktlink - ] |
01.04.2004, 14:17 Uhr gni Posts: 1106 Nutzer |
Zitat:Nein. Zitat:Richtig. Zitat:Wenn die normale GCC Installation andere Header verwendet, funktioniert das nicht. [ - Antworten - Zitieren - Direktlink - ] |
02.04.2004, 16:23 Uhr Mad_Dog Posts: 1944 Nutzer |
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. ![]() -- http://www.norman-interactive.com [ - Antworten - Zitieren - Direktlink - ] |
02.04.2004, 17:01 Uhr gni Posts: 1106 Nutzer |
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. [ - Antworten - Zitieren - Direktlink - ] |
02.04.2004, 17:22 Uhr Mad_Dog Posts: 1944 Nutzer |
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 [ - Antworten - Zitieren - Direktlink - ] |
02.04.2004, 17:29 Uhr Mad_Dog Posts: 1944 Nutzer |
Übrigens: Es muß Sierpinski heißen. ![]() -- http://www.norman-interactive.com [ - Antworten - Zitieren - Direktlink - ] |
02.04.2004, 18:02 Uhr Solar Posts: 3680 Nutzer |
Zitat: Öhm... ich glaube Du verwechselst mich mit jemandem. SFS habe ich nie genutzt, geschweige den compiliert. ![]() [ - Antworten - Zitieren - Direktlink - ] |
02.04.2004, 18:15 Uhr Mad_Dog Posts: 1944 Nutzer |
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 [ - Antworten - Zitieren - Direktlink - ] |
02.04.2004, 20:00 Uhr Palgucker Posts: 1342 Nutzer |
@ 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 [ - Antworten - Zitieren - Direktlink - ] |
03.04.2004, 01:37 Uhr obw Posts: 94 Nutzer |
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 [ - Antworten - Zitieren - Direktlink - ] |
03.04.2004, 10:38 Uhr Mad_Dog Posts: 1944 Nutzer |
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. ] [ - Antworten - Zitieren - Direktlink - ] |
03.04.2004, 13:34 Uhr whose Posts: 2156 Nutzer |
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 [ - Antworten - Zitieren - Direktlink - ] |
03.04.2004, 20:11 Uhr Mad_Dog Posts: 1944 Nutzer |
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 [ - Antworten - Zitieren - Direktlink - ] |
04.04.2004, 14:42 Uhr Palgucker Posts: 1342 Nutzer |
@ 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. ] [ - Antworten - Zitieren - Direktlink - ] |
04.04.2004, 19:10 Uhr Mad_Dog Posts: 1944 Nutzer |
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 [ - Antworten - Zitieren - Direktlink - ] |
05.04.2004, 11:48 Uhr gni Posts: 1106 Nutzer |
Zitat:Na sowas, Helios != Solar. [ - Antworten - Zitieren - Direktlink - ] |
05.04.2004, 11:54 Uhr gni Posts: 1106 Nutzer |
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). [ - Antworten - Zitieren - Direktlink - ] |
05.04.2004, 12:18 Uhr Solar Posts: 3680 Nutzer |
Zitat: true. ![]() [ - Antworten - Zitieren - Direktlink - ] |
05.04.2004, 12:24 Uhr gni Posts: 1106 Nutzer |
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. [ - Antworten - Zitieren - Direktlink - ] |
05.04.2004, 13:02 Uhr gni Posts: 1106 Nutzer |
Zitat:"IntBase" ist dem Compiler völlig egal. [ - Antworten - Zitieren - Direktlink - ] |
05.04.2004, 14:11 Uhr Mad_Dog Posts: 1944 Nutzer |
Zitat: Wobei in die proto-Header laut Kommentar ursprünglich für Lattice C gedacht waren. -- http://www.norman-interactive.com [ - Antworten - Zitieren - Direktlink - ] |
05.04.2004, 14:14 Uhr Mad_Dog Posts: 1944 Nutzer |
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. ] [ - Antworten - Zitieren - Direktlink - ] |
05.04.2004, 17:25 Uhr gni Posts: 1106 Nutzer |
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. [ - Antworten - Zitieren - Direktlink - ] |
05.04.2004, 17:34 Uhr gni Posts: 1106 Nutzer |
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). [ - Antworten - Zitieren - Direktlink - ] |
06.04.2004, 14:17 Uhr Mad_Dog Posts: 1944 Nutzer |
-- Doppelposting gelöscht -- [ Dieser Beitrag wurde von Mad_Dog am 06.04.2004 editiert. ] [ - Antworten - Zitieren - Direktlink - ] |
06.04.2004, 14:18 Uhr Mad_Dog Posts: 1944 Nutzer |
Zitat: Das frage ich mich langsam auch. ![]() Zitat: Schon klar. ![]() Falls noch jemand was an meinem C-Kurs auszusetzen hat, dann können wir das gerne hier ausdisskutieren. ![]() -- http://www.norman-interactive.com [ Dieser Beitrag wurde von Mad_Dog am 06.04.2004 editiert. ] [ - Antworten - Zitieren - Direktlink - ] |
1 2 3 4 -5- | [ - Beitrag schreiben - ] |
amiga-news.de Forum > Programmierung > C-Anfängerkurs | [ - Suche - Neue Beiträge - Registrieren - Login - ] |
![]() |
Impressum |
Datenschutzerklärung |
Netiquette |
Werbung |
Kontakt
Copyright © 1998-2025 by amiga-news.de - alle Rechte vorbehalten. |
![]() |