GCC zickt rum



  • Moin!
    Ich will grad ein Poker-Programm schreiben, aber irgendwie kapiert mein Compiler (GCC) nicht, was ich von ihm will, bzw. ich kapiere nicht, was er von mir will, denn er erzählt mir totale Scheiße. Also eigentlich ist er schuld.
    Könnt ihr mir trotzdem sagen, was ich falsch mache?
    Datei: types.h

    #ifndef TYPES
    #define TYPES
    
    typedef enum{c_clubs, c_spades, c_hearts, c_diamonds} t_suit;
    typedef enum{v_2, v_3, v_4, v_5, v_6, v_7, v_8, v_9, v_10, v_j, v_q, v_k, v_a} t_value;
    
    typedef struct
    {
    	t_suit suit;
    	t_value value;
    	int id;
    } Card;
    #endif
    

    Datei: const.h

    #ifndef CONST
    #define CONST
    #include "types.h"
    
    const Card theCards[52]={
    {c_clubs, v_a, 0}, {c_clubs, v_k, 1}, {c_clubs, v_q, 2}, {c_clubs, v_j, 3}, {c_clubs, v_10, 4}, {c_clubs, v_9, 5}, {c_clubs, v_8, 6}, {c_clubs, v_7, 7}, {c_clubs, v_6, 8}, {c_clubs, v_5, 9}, {c_clubs, v_4, 10}, {c_clubs, v_3, 11}, {c_clubs, v_2, 12},
    {c_spades, v_a, 13}, {c_spades, v_k, 14}, {c_spades, v_q, 15}, {c_spades, v_j, 16}, {c_spades, v_10, 17}, {c_spades, v_9, 18}, {c_spades, v_8, 19}, {c_spades, v_7, 20}, {c_spades, v_6, 21}, {c_spades, v_5, 22}, {c_spades, v_4, 23}, {c_spades, v_3, 24}, {c_spades, v_2, 25},
    {c_hearts, v_a, 26}, {c_hearts, v_k, 27}, {c_hearts, v_q, 28}, {c_hearts, v_j, 29}, {c_hearts, v_10, 30}, {c_hearts, v_9, 31}, {c_hearts, v_8, 32}, {c_hearts, v_7, 33}, {c_hearts, v_6, 34}, {c_hearts, v_5, 35}, {c_hearts, v_4, 36}, {c_hearts, v_3, 37}, {c_hearts, v_2, 38},
    {c_diamonds, v_a, 39}, {c_diamonds, v_k, 40}, {c_diamonds, v_q, 41}, {c_diamonds, v_j, 42}, {c_diamonds, v_10, 43}, {c_diamonds, v_9, 44}, {c_diamonds, v_8, 45}, {c_diamonds, v_7, 46}, {c_diamonds, v_6, 47}, {c_diamonds, v_5, 48}, {c_diamonds, v_4, 49}, {c_diamonds, v_3, 50}, {c_diamonds, v_2, 51}
    };
    
    const Card nocard={-1,-1,-1};
    
    // ... Punkt Punkt Punkt ...
    
    #endif
    

    Nun sagt mir mein GCC folgendes:

    const.h:7: error: 'Card' does not name a type
    const.h:12: error: invalid conversion from int to t_suit
    const.h:12: error: invalid conversion from int to t_type
    poker.cpp: error: nocard undeclared
    

    Ich hab in der poker.cpp beide Header included.
    Ich weiß nicht, warum GCC den Typ 'Card' nicht mag. Bei der Deklaration von theCards behauptet er ja einfach nur, der Typ sei nicht deklariert. Dann bei der Deklaration von nocard bemängelt er auf einmal diese type-conversions, von denen er ja eigentlich gar nichts wissen könnte, wenn er den Typ Card nicht kennt.😕
    Und warum er letzteres überhaupt bemängelt kapier ich auch nicht. Ich dachte, enum wären mit int quasi gleichwertig oder so?
    Wenn ich die Deklarationsreihenfolge der beiden Konstanten umdrehe, sagt er übrigens nur, dass 'Card' undeklariert ist und überhaupt nichts von den conversions.
    Ist mein Compiler doof oder ich?

    Moritz



  • Erstmal schreibt man unter C++ nicht mehr "typedef struct{...}name;", sondern "struct name{...};" (und analog für die enum's). Und zweitens existiert unter C++ keine implizite Umwandlung von int nach enum (aber du könntest den enum's einen zusätzlichen Wert c_none bzw. v_none für "keine Karte" mitgeben).



  • Hmm, danke für den Hinweis. Hab das mit dem typedef geändert. Hat aber leider nicht geholfen.
    Er sagt immer noch genau das gleiche. 😞

    Und noch mal was anderes:
    Wenn ich

    #include <iostream>
    

    mache und dann cout benutzen will, sagt er mir, cout ist nicht deklariert. Wenn ich statt dessen

    #include <iostream.h>
    

    mache, versteht er cout, warnt mich aber, weil <iostream.h> "deprecated" ist und ich lieber <iostream> schreiben soll.
    Irgendwie hat der doch ne Macke, oder?

    Ich versteh das alles nicht. Ich schreib ja eh immer so'n komischen C/C++-Mischmasch, weil ich nie nach irgendeinem Standard gelernt hab, sondern immer nur das gemacht hab, was mein jeweiliger Compiler gerade akzeptiert hat. Und meistens hab ich mit Visual C++ gearbeitet, wenn ich mal was programmiert hab, was ja eh kein Standard C++ ist. Aber irgendwie scheint mir das, was ich jetzt geschrieben hab, doch ziemlich Standard-ISO-C++ zu sein, oder nicht? Und ich dachte, GCC richtet sich nach dem Standard. 😕 Oder mach ich immer noch irgendwas falsch?



  • Du machst noch immer was falsch. Wenn du die neuen Header benutzt, also "#include <iostream>", dann musst du wissen, dass alles in den Namensraum "std" verfrachtet wurde.

    Siehe dafür auch: http://tutorial.schornboeck.net/namespace.htm

    Zum Anderen dein Problem mit den enums. Du kannst die Werte natürlich mittels static_cast< > casten. Siehe hier: http://tutorial.schornboeck.net/casts.htm

    MfG

    GPC



  • Hast du mal versucht, 'Card' einen Ctor zu spendieren (und bei der Initialisierung des Arrays zu nutzen)? Ansonsten sehe ich den Sinn deines Arrays nicht ein - ich hätte der Karte "nur" einen int-Wert übergeben und daraus bei Bedarf Farbe und Wert ermittelt:

    class Card
    {
    public:
      Card(t_suit c,t_value v) : id(c+4*v) {}
      t_suit get_suit() {return (t_suit)(id%4); }
      t_value get_value() {return (t_value)(id/4); }
    
    private:
      int id;
    };
    

    @<iostream> vs <iostream.h>:
    Die Standard-Header packen alle Definitionen in den Namensraum 'std'. Das heißt, du mußt die Daten nach '**std::**cout' leiten (oder den Namen per using std::cout; bzw. using namespace std; global bekanntmachen. <iostream.h> ist, wie dein Compiler richtig erkannt hat, veraltet und sollte nicht mehr verwendet werden.



  • Krecik schrieb:

    Ich versteh das alles nicht. Ich schreib ja eh immer so'n komischen C/C++-Mischmasch, weil ich nie nach irgendeinem Standard gelernt hab, sondern immer nur das gemacht hab, was mein jeweiliger Compiler gerade akzeptiert hat. Und meistens hab ich mit Visual C++ gearbeitet, wenn ich mal was programmiert hab, was ja eh kein Standard C++ ist. Aber irgendwie scheint mir das, was ich jetzt geschrieben hab, doch ziemlich Standard-ISO-C++ zu sein, oder nicht? Und ich dachte, GCC richtet sich nach dem Standard. 😕 Oder mach ich immer noch irgendwas falsch?

    Einfach so lange ändern, bis der Compiler es versteht und dann sagen, daß der GCC rum zickt. Da frage ich mich, wer wirklich rum zickt.

    Das ist so, als würdest Du einen Menschen, der deine Sprache nicht spricht, so lange zutexten, bis der was vernüftiges versteht. Und wenn er es nicht versteht zu behaupten, er zicke rum. 😃

    Wie wäre es, wenn Du mal C++ lernst?



  • @CStoll: Du hast recht. Das ist eigentlich viel vernünftiger.
    Trotzdem frage ich mich, warum das mit struct Card... nicht funktioniert hat.

    @tntnet: Ich hab mal vor 7 Jahren C++ gelernt. Aber da war der Standard vielleicht noch anders als es jetzt ist, oder in dem Buch, was ich gelesen hab war es halt anders, und einen Standard-Compiler hatte ich eh nie, und das war mir auch alles zu anstrengend. Aber vielleicht lern ich das demnächst ja noch mal. Was mich immer davon abgehalten hat, waren zum Beispiel auch solche Probleme wie das mit dieser nicht funktionierenden Typendeklaration jetzt, die ich nicht verstehen konnte und jetzt immer noch nicht kann. Und das blöde Fragen stellen und keine Antwort kriegen. Hast du eine Erklärung, warum das mit der struct-Card-Deklaration nicht geklappt hat?
    Auf jeden Fall finde ich, ein Compiler sollte sich immer so verhalten, wie ich es gerade für richtig halte. Das Gegenteil wäre nämlich die Definition von Rumzicken. 😃



  • Krecik schrieb:

    Auf jeden Fall finde ich, ein Compiler sollte sich immer so verhalten, wie ich es gerade für richtig halte. Das Gegenteil wäre nämlich die Definition von Rumzicken. 😃

    Vielleicht läßt du den Compiler die Programme demnächst selbst schreiben...
    btw: Kannst dich melden, wenn du ein Programm entwickelt hast, dass die Diagonalsprache entscheidet 😃



  • Diagonalsprache kann ich. Ich les immer diagonal.

    So langsam hab ich das Gefühl, meinem GCC kann nur C kompilieren und für C++ fehlt ihm irgendwas. Wenn im Quellcode sonst nix mehr zu meckern ist, erzählt er mir dauernd was von undefined reference to std::blah::blub::undsoweiter() und undefined reference to operator delete[](void*) und to operator new...blah etc.
    Wenn ich alles mit printf, malloc, free etc. mache, geht alles.
    Muss ich vielleicht noch irgendwelche Umgebungsvariablen irgendwie setzten oder so'n Zeugs oder dem Compiler noch sagen, dass er irgendwelche C++-Sachen noch braucht, die er irgendwo vergessen hat?

    Und wenn ich alles zusammen in eine Datei quetsche, funktionieren auch die Typendeklarationen, also nichts mehr mit undeclared type. Wenn ich in einem Header ne Klasse deklariere und die include, macht er den gleichen Scheiß wie oben mit der struct.
    Vielleicht übersetz ich's auch lieber wieder von Hand in Maschinencode. Hab ich letztens immer so gemacht, aufm Blatt Papier, weil das auch nicht abstürzt und so...

    Hmm, und dann auch noch undefined reference to WinMain@16 auf einmal in der zusammengewurschtelten poker.cpp, wo absolut nichts windowsmäßiges drin auftaucht. Ich find das super.
    Aber das Programm funktioniert:
    claas.h

    class claas
    {
    public:
    	void yay()
    	{
    		printf("yay!\n");
    	}
    };
    

    klaus.cpp

    //#include <iostream>
    #include <stdio.h>
    #include "claas.h"
    //using namespace std;
    
    int main()
    {
    	claas klaus;
    	klaus.yay();
    	return 0;
    }
    


  • kann es sein, dass du die falschen parameter zum kompilieren benutzst?



  • Jo, kann sein.
    Ich hab erst mal überhaupt keine benutzt, also:

    gcc poker.cpp -o poker.exe
    

    Hab jetzt grad mal auf die Schnelle DevC++ installiert, was ja auch den GCC benutzt, an den Standard-Einstellungen nirgends was geändert.
    Da krieg ich für jedes Projekt (auch für so ein vorgeneriertes, leeres Standardprojekt wie folgendes)

    #include <cstdlib>
    #include <iostream>
    
    using namespace std;
    
    int main(int argc, char *argv[])
    {
        system("PAUSE");
        return EXIT_SUCCESS;
    }
    

    vom Linker die dubiose Fehlermeldung:

    undefined reference to '__cpu_features_init'
    ld returned 1 exit status
    

    Sonst aber keine unerwarteten Kompilier-Fehler mehr.



  • g++, hier ist g++ angesagt.. jedoch:

    scheint ein dev cpp problem zu sein, wenn man danach googlet, findet man es zu hauf. recherchier, wenn es nicht mit g++ geht, mal nach deinem linkerfehler. bzw:
    installier eine andere version, oder einen anderen compiler.



  • Krecik schrieb:

    Jo, kann sein.
    Ich hab erst mal überhaupt keine benutzt, also:

    gcc poker.cpp -o poker.exe
    

    Dem "fehlt nicht" irgendwas für C++, Du hast schlicht und ergreifend statt dem C++-Compiler den für C verwendet. Der andere heisst g++.



  • Dieser Thread wurde von Moderator/in HumeSikkins aus dem Forum C++ in das Forum Compiler- und IDE-Forum verschoben.

    Im Zweifelsfall bitte auch folgende Hinweise beachten:
    C/C++ Forum :: FAQ - Sonstiges :: Wohin mit meiner Frage?

    Dieses Posting wurde automatisch erzeugt.



  • Sorry, ist Offtopic aber muss sein.
    benutz nicht dev-cpp. Ist zwar die einfachste art, die ich bisher gesehen habe um etwas zum laufen zu bringen (=kompilieren). Aber das ist, zumindest bei mir, viel zu oft abgestürzt, und damit war manchmal stundenlange arbeit verloren. codeblocks ist besser. Ist zwar auch ab und zu abgestürzt, der hat aber automatische speicherung.
    Außerdem wird Dev-Cpp scheinbar nicht mehr weiterentwickelt. Der letzte Update ist auch schon >2 Jahre her.



  • Der Threadverlauf ist einfach nur genial! Es bestätigt sich immer wieder: Das Problem sitzt meistens nicht im Computer, sondern davor! 😃 👍


Log in to reply