Frischling Visual C++



  • Hallo Leute 🙂

    bin gerade beim Umstieg auf Visual C++ und musste feststellen dass VC++ nicht das gleiche ist wie C++ *schluchz*.

    1. Als Beispiel für eines der Probleme: CString

    Eigentlich steht nix drin. Daher auch die Frage: Warum funtkioniert das nicht?
    Laut MSDN und Forum hier ist die Deklaration der CString richtig.

    #include "stdafx.h"
    #include <cstring>
    
    int main(int argc, char* argv[])
    {
        Cstring test = "aaa";
        return 0;
    }
    

    Fehlermeldungen sind folgende:

    C:\ArbOs\Foo.cpp(17) : error C2065: 'CString' : nichtdeklarierter Bezeichner
    C:\ArbOs\Foo.cpp(17) : error C2146: Syntaxfehler : Fehlendes ';' vor Bezeichner 'test'
    C:\ArbOs\Foo.cpp(17) : error C2065: 'test' : nichtdeklarierter Bezeichner
    C:\ArbOs\Foo.cpp(17) : error C2440: '=' : 'char [4]' kann nicht in 'int' konvertiert werden
    Diese Konvertierung erfordert einen reinterpret_cast-Operator oder eine Typumwandlung im C- oder Funktionsformat

    Anmerkung: Ich würde das ja verstehen wenn er die "CString.h" nicht gefunden hätte - aber das ist nicht der Fall...

    EDIT:
    habe mal anstatt <cstring> die <afx.h> included (so wie es in der MSDN Library steht) und bekomme drei ganz andere Fehlermeldungen:

    nafxcwd.lib(afxmem.obj) : error LNK2005: "void __cdecl operator delete(void *)" (??3@YAXPAX@Z) bereits in libcpd.lib(delop.obj) definiert
    nafxcwd.lib(thrdcore.obj) : error LNK2001: Nichtaufgeloestes externes Symbol __endthreadex
    nafxcwd.lib(thrdcore.obj) : error LNK2001: Nichtaufgeloestes externes Symbol __beginthreadex

    2. ich will die COleDateTime verwenden, include die Datei die in der MSDN als Header angegeben ist und kriege 3 Fehler... -> unlogisch (hab nur included... sonst nix).

    PS: Bin bisher nur mit DevCpp und Borland C++ Builder unterwegs gewesen - da hatte ich derart merkwürdige Fehler nicht.

    schonmal danke im Vorraus

    gruß Tobi



  • Cstring != CString



  • It0101 schrieb:

    bin gerade beim Umstieg auf Visual C++ und musste feststellen dass VC++ nicht das gleiche ist wie C++ *schluchz*.

    Unter Visual C++ kannst du genauso C++ schreiben wie unter anderen IDEs. Ich sehe aus deinen Post aber nicht was du genau programmieren willst.

    Möchtest du mit der MFC Programmieren (Sonst bist du im falschen Forum, dann wärst du besser im C++ oder Compilerforum aufgehoben) oder soll es erstmal Ansi C++ sein?

    It0101 schrieb:

    1. Als Beispiel für eines der Probleme: CString

    Wie schon von HollyBolly erwähnt: C-String ist nicht CString. Der Header <cstring> ist aber der Header der C-Bibliothek zu C-Strings (Frag mich jetzt nicht in welchen CString steht, ich programmiere auch unter VC keine MFC-Programme und verwende zudem auch keine precompiled Header).

    It0101 schrieb:

    habe mal anstatt <cstring> die <afx.h> included (so wie es in der MSDN Library steht) und bekomme drei ganz andere Fehlermeldungen:

    Ich nehme an das du dafür auch einige Projekteinstellungen ändern musst. Zudem weiß ich nicht welche VC-Version einsetzt (Die Expressversionen kennen kein MFC).

    cu André



  • Ich verwende keine MFC, da ich momentan kein Frontend basteln will sondern nur eine Konsolenanwendung. Und da war ich auf der Suche nach einer String-Klasse ähnlich wie z.B. AnsiString im Borland C++ Builder.

    Habe zuerst versucht <string> zu includen, so wie ich das bei DevCpp auch immer verwende, aber das ist auch gescheitert. Er hat <string> included, aber eben den Datentyp "string" nicht gefunden...

    EDIT: ich verwende Visual C++ 6.0 Enterprise Edition

    EDIT2: Welche String-Klasse würdet ihr mir denn für eine Konsolenanwendung empfehlen? Ich brauch so Dinge wie Laden und Schreiben in Datei und Casten in COleDateTime und ähnliches. Also praktisch nur Standardkrams.

    Was ist nun eigentlich LPCSTR? Der MSDN hab ich entnommen dass es eigentlich nur ein const char* ist. Trifft das zu?



  • Nimm mal die atlstr.h. CString gehört zur ATL und nicht mehr zur MFC.
    Falls das nicht reicht, musst du etvl in den Projektoptionen einstellen, dass er die ATL mitlinkt. Da CString aber auf das Template CStringT aufbaut, also ein Template ist, müssten alle Infos der er braucht in den HEaderdateien stehen.

    Ansonsten reicht dir evtl auch der std::string aus der STL aus. (header <string>)



  • Jetzt wo du das sagst fällt mir ein dass ich den namespace beim verwenden der "string" vergessen habe...

    Man scheisse warum sind Microsoftfehlermeldungen nur so kryptisch ^^

    Die Umgewöhnung von Borland C++ Builder ist echt schwer 😉



  • EDIT: ich verwende Visual C++ 6.0 Enterprise Edition

    Wen du keine MFC/ATL brauchst, dann zieh dir die kostenlose VS 2008 Express-Edition. VS 06 ist alt und nicht sehr ISO-konform in einigen Dingen.

    Man scheisse warum sind Microsoftfehlermeldungen nur so kryptisch ^^

    Gewöhnungssache. Die Fehlermeldung war ja korrekt: string war ihm nicht bekannt. Also muss überlegen, warum er die Klasse nicht findet. Woher soll der Compiler wissen, dass es irgendwo in irgendeinem namespace string gibt?

    Was ist nun eigentlich LPCSTR? Der MSDN hab ich entnommen dass es eigentlich nur ein const char* ist. Trifft das zu?

    "Long Pointer Const String" oder so ähnliuch ausgesprochen. Im VS 06 wäre das standardmäßig ein typedef auf "const char*"



  • Ok danke euch erstmal für eure Ausführungen. Ich kann leider die Entwicklungsumgebnung nicht wechseln, weil die Firma das so vorgibt 😉

    Neuer Arbeitstag neues Glück 🙂 (ich bin optimistisch, dass das Vergessen des Namespace der böseste Fehler war 🙂 )



  • It0101 schrieb:

    EDIT: ich verwende Visual C++ 6.0 Enterprise Edition

    Das kann bereits einige Probleme erklären. VC++ 6.0 ist stark veraltet, nicht standardkonform, und sollte wenn nicht durch ein Projekt aufgezwungen auch lieber nicht mehr verwendet werden.

    Ganz davon abgesehen läuft <string> auch unter VC++ 6.0:
    (Minimalprogramm, angelegt über neues Projekt, Win32 Konsolenanwendung, Leeres Projekt; Hinzufügen der folgenden Datei)

    #include <string>
    #include <iostream>
    
    int main()
    {
      std::string text;
      std::cin >> text;
      std::cout << text;
      std::cin >> text;
    }
    

    Alternativ auch mit "using namespace std;", nur beachten das man dies nicht im Header macht.

    cu André



  • jop, das war auch des rätsels lösung 🙂

    Neue Entwicklungsumgebungen verwirren mich... ^^ Leider komm ich nicht drumherum.

    for (unsigned int i = 0; i < Watchlist.size(); i++)
    {
    }
    for (unsigned int i = 0; i < Watchlist.size(); i++)
    {
    }
    

    führt zu

    'i' : Neudefinition; Mehrfachinitialisierung

    C++ Spezifikation sagt aber meines Wissen eigentlich, dass die Variable i bei lokaler Deklaration in einer Schleife, nach Beenden dieser Schleife nicht mehr bekannt sein sollte. D.h. dass ich die ohne Probleme wiederverwenden kann. (so kenn ich das auch aus C++ Builder und DevCpp)

    Wie kann ich das bei Visual C++ einstellen, dass er sich daran auch hält?



  • It0101 schrieb:

    Wie kann ich das bei Visual C++ einstellen, dass er sich daran auch hält?

    In VC6 gar nicht. Stimmen zu den Standard-Inkompatibilitäten von VC6 gab es hier ja schon genug, deswegen halte ich mich da mal zurück.



  • ok danke 🙂 Die Antwort reicht mir auch schon 😉



  • Naja, da gibts defines für sowas.

    #define for if(0){}else for
    

    IMO müsste das so gehen. Ggf. selber im inet suchen, ist ein bekannter workaround für den MSVC for-scope-bug.

    EDIT: scheint dass ich mich richtig erinnert habe: http://www.google.com/search?hl=en&safe=off&q=%22%23define+for+if(0)%7B%7Delse+for%22&start=10&sa=N

    Die verwenden zwar alle ";" statt "{}", sollte aber denke ich mal egal sein.



  • It0101 schrieb:

    Neue Entwicklungsumgebungen verwirren mich...

    In diesem Fall eine alte. VC++ 6.0 ist nun etwa 10 Jahre alt, deine weiteren Probleme liegen an seiner mangelnden Standardkonformität.

    It0101 schrieb:

    for (unsigned int i = 0; i < Watchlist.size(); i++) {}
    for (unsigned int i = 0; i < Watchlist.size(); i++) {}
    

    führt zu

    'i' : Neudefinition; Mehrfachinitialisierung

    Fehler im VC++ 6.0, wenn ich mich nicht irre auch nicht abschaltbar. Eine Möglichkeit wäre es die Schleifen in eigene Scopes ({}) zu setzen. Davon abgesehen wäre ich sehr vorsichtig hier Compilerschalter umzusetzen, da es das Gesamtprojekt betrifft, und sich dies auch auf andere Entwickler auswirkt.

    Zwei kleine Anmerkungen dennoch:

    a) ++i ist i++ vorzuziehen
    b) Watchlist.size() wird so wie du es angibst mit jedem Schleifendurchgang aufs neue ausgeführt. IMHO besser:

    for (unsigned int i = 0, count=Watchlist.size(); i < count; ++i) // ...
    

    Wie kann ich das bei Visual C++ einstellen, dass er sich daran auch hält?

    Wie oben schon angegeben glaube ich nicht das es so ohne weiteres geht, zudem würde es das Gesamtprojekt beeinflussen. Es gibt aber noch gravierendere Probleme beim VC6.
    a) Templateumsetzung
    b) Standardbibliothek
    c) Verhalten von new

    Zu letzteren: Unter Compilern die sich an den Standard halten wirft new im Fehlerfall eine Exception, unter alten Compilern gibt es statt dessen ein NULL-Zeiger zurück (Hier kann soviel ich weiß der Header <new> etwas ändern, näheres siehe aber MSDN der 6er Version...).

    cu André


Anmelden zum Antworten