C++ lernen

Status
Für weitere Antworten geschlossen.
VikingGe schrieb:
[...] für volatile gilt zunächst einmal das gleiche, nur dass man volatile ganz gut dazu verwenden kann, die Erkennung von möglichen Race Conditions dem Compiler zu überlassen, wenn man in einer Multithread-Umgebung ist.

Wie das? Erklär mal. Warum ich frage? Weil die Tauglichkeit von volatile für Threading-Geschichten ganz und gar compiler-abhängig ist. Der Standard macht dazu keine Aussagen. Ich würde also lieber gleich die Finger davon lassen und stattdessen auf gescheite Synchronisationsprimitive setzen.

http://stackoverflow.com/questions/4557979/when-to-use-volatile-with-multi-threading


EDIT: Ah, beim weiteren Lesen bin auf die Strategie gestoßen, die du wahrscheinlich meintest ( http://www.drdobbs.com/cpp/volatile-the-multithreaded-programmers-b/184403766 ). Dieser Einsatz von volatile ist total neu für mich ... das muß ich erst mal verdauen.
 
Zuletzt bearbeitet:
VikingGe schrieb:
gibts für Windows einen Compiler, der in Sachen C++11-Unterstützung ungefähr auf dem Level von GCC 4.7 ist?
Auf die Gefahr hin, mich mangels konkretem Wissens zum Vollidioten zu machen: Wie wäre es mit GCC?

€: Ich habe gerade mal spaßeshalber mingw32 installiert und bekomme folgende Ausgabe:
Code:
Q:\Programme\mingw\bin>g++ -v
Using built-in specs.
COLLECT_GCC=g++
COLLECT_LTO_WRAPPER=q:/programme/mingw/bin/../libexec/gcc/mingw32/4.8.1/lto-wrap
per.exe
Target: mingw32
Configured with: ../gcc-4.8.1/configure --prefix=/mingw --host=mingw32 --build=m
ingw32 --without-pic --enable-shared --enable-static --with-gnu-ld --enable-lto
--enable-libssp --disable-multilib --enable-languages=c,c++,fortran,objc,obj-c++
,ada --disable-sjlj-exceptions --with-dwarf2 --disable-win32-registry --enable-l
ibstdcxx-debug --enable-version-specific-runtime-libs --with-gmp=/usr/src/pkg/gm
p-5.1.2-1-mingw32-src/bld --with-mpc=/usr/src/pkg/mpc-1.0.1-1-mingw32-src/bld --
with-mpfr= --with-system-zlib --with-gnu-as --enable-decimal-float=yes --enable-
libgomp --enable-threads --with-libiconv-prefix=/mingw32 --with-libintl-prefix=/
mingw
Thread model: win32
gcc version 4.8.1 (GCC)

Und laut http://gcc.gnu.org/
GCC 4.8.1 will be C++11 feature-complete [2013-04-01]
Support for C++11 ref-qualifiers was added to the GCC 4.8 branch, making G++ the first C++ compiler to implement all the major language features of the C++11 standard. This functionality will be available in GCC 4.8.1.

Ich denke, damit sollte dein Wunsch erfüllt sein :3
 
Zuletzt bearbeitet: (Sachen)
VikingGe schrieb:
für volatile gilt zunächst einmal das gleiche, nur dass man volatile ganz gut dazu verwenden kann, die Erkennung von möglichen Race Conditions dem Compiler zu überlassen, wenn man in einer Multithread-Umgebung ist.

? ? ?
 
EDIT: Ah, beim weiteren Lesen bin auf die Strategie gestoßen, die du wahrscheinlich meintest ( http://www.drdobbs.com/cpp/volatile-...rs-b/184403766 ). Dieser Einsatz von volatile ist total neu für mich ... das muß ich erst mal verdauen.

Exakt - der Artikel hat mich auch drauf gebracht.

€: Ich habe gerade mal spaßeshalber mingw32 installiert und bekomme folgende Ausgabe:
Oh super :D Haben sie das also tatsächlich mal geupdated, das war vor ner Weile noch auf dem Stand von GCC 4.5, keine Chance, damit auch nur irgendwas zu bauen.
 
Zuletzt bearbeitet:
asdfman schrieb:
Das geht so weit, dass manche Menschen in völliger Verwirrung solch Hirnakrobatik vollführen, wie von "C/C++" zu sprechen.
von C/C++ zu sprechen, ist weder eine Hirnakrobatik noch etwas, das man in völliger Verwirrung tut. Ich will nicht ausschließen, dass man in C++ komplett ohne die Verwendung von C-Konstrukten programmieren kann, bisweilen ist der Rückgriff auf C-Konstrukte aber immer noch die komfortablere Lösung. Beispiel: ich will Zahlen in einen String schreiben. In C macht man das mit sprintf(). In C++ gibt es dafür Stringstreams, alternativ kann aber auch wie in C sprintf() verwenden. Und in den allermeisten Fällen ist sprintf() eindeutig die praktikablere Lösung. Und so Sachen wie memcpy() und memset() sind in C++ zuweilen auch noch ganz nützlich. Sogar was die Ausgabe auf die Kommandozeile angeht, ist printf() dem cout << in einer nicht unwesentlichen Menge an Fällen überlegen.

F_GXdx schrieb:
C ist aber eine Untermenge von C++, das heißt, man könnte C-Libs in C++ verwenden, wenn man ein böser Programmierer ist.
was soll der Konjunktiv? Man könnte nicht nur, man kann. Allerdings ist das nicht wirklich ein Argument, denn dass man in der einen Programmiersprache Libs verwenden kann, die in der anderen geschrieben sind, gilt für viele Paare von Programmiersprachen. Eine durchaus häufige Kombo ist C/Fortran. Man muss dabei wissen, dass die fertige Lib als Maschinencode vorliegt und somit weitestgehend sprachunabhängig ist.

character schrieb:
Das stimmt nicht. C und C++ überschneiden sich lediglich an einigen Stellen.

Oder anders: Es gibt eine Teilmenge von C, die auch auch eine Teilmenge von C++ ist, aber selbst dann gibt es noch Stellen mit unterschiedlichem Verhalten bei gleicher Syntax.

Man kann einem C++-Compiler nicht einfach C-Code geben und erwarten, dass alles funktioniert (weder syntaktisch noch semantisch).
dann bring doch mal ein Beispiel für einen C-Code vor, wo das deiner Ansicht nach so sein soll.
 
C ist aber eine Untermenge von C++, das heißt, man könnte C-Libs in C++ verwenden, wenn man ein böser Programmierer ist.
Ich sehe nicht, was daran böse sein soll. Es gibt nen Haufen Bibliotheken, die eben nur ein C-Style-API haben, mir fällt außer Qt jetzt auf Ahnhieb sogar keine einzige ein, wo dem nicht so ist - sicher für den C++-Programmierer nicht schön, aber böse? Wohl kaum.

dann bring doch mal ein Beispiel für einen C-Code vor, wo das deiner Ansicht nach so sein soll.
Da gibt es allerdings schon was - allein schon das explizite Casten von Void-Pointern in C++. Siehe auch Compatibility of C and C++ bei Wikipedia.
 
Sculletto schrieb:
Beispiel: ich will Zahlen in einen String schreiben. In C macht man das mit sprintf(). In C++ gibt es dafür Stringstreams, alternativ kann aber auch wie in C sprintf() verwenden. Und in den allermeisten Fällen ist sprintf() eindeutig die praktikablere Lösung.

Wieso? Der einzige Nachteil der iostreams, der mir im Moment einfällt, ist daß sie performance-technisch in der Regel nicht so dolle sind, aber das liegt an der suboptimalen Implementierung und ist nicht prinzipbedingt. Wie Scott Meyers einmal anmerkte, steht sogar zu hoffen, daß früher oder später mal eine Implementierung auftaucht, die wesentlich flotter ist als printf & co, da iostreams keinen Formatstring parsen müssen, um an Typ-und Formatierungsinformation zu kommen.

Aber egal, was ist an std:ostringstream (für std::string-Objekte) oder std::ostrstream (für char-Arrays) nicht praktikabel?

Sculletto schrieb:
Und so Sachen wie memcpy() und memset() sind in C++ zuweilen auch noch ganz nützlich.

Ich wüßte nicht wozu. Außer in ganz wenigen Ausnahmefällen.
 
Sculletto schrieb:
von C/C++ zu sprechen, ist weder eine Hirnakrobatik noch etwas, das man in völliger Verwirrung tut. Ich will nicht ausschließen, dass man in C++ komplett ohne die Verwendung von C-Konstrukten programmieren kann, bisweilen ist der Rückgriff auf C-Konstrukte aber immer noch die komfortablere Lösung. Beispiel: ich will Zahlen in einen String schreiben. In C macht man das mit sprintf(). In C++ gibt es dafür Stringstreams, alternativ kann aber auch wie in C sprintf() verwenden. Und in den allermeisten Fällen ist sprintf() eindeutig die praktikablere Lösung. Und so Sachen wie memcpy() und memset() sind in C++ zuweilen auch noch ganz nützlich. Sogar was die Ausgabe auf die Kommandozeile angeht, ist printf() dem cout << in einer nicht unwesentlichen Menge an Fällen überlegen.
Gebau die von dir beschriebenen Dinge sind Sachen die man zwar oft sieht und hört, aber zu den Dingeb gehören die man tunlichst vermeiden sollte.
Das ist genauso eine Sache wie heutzutage Hardpointer zu verwenden wenn es nicht eben sein muss.
Gründe dafür kann man zu genüge in Büchern oder im Internet finden.
 
Sculletto schrieb:
von C/C++ zu sprechen, ist weder eine Hirnakrobatik noch etwas, das man in völliger Verwirrung tut. Ich will nicht ausschließen, dass man in C++ komplett ohne die Verwendung von C-Konstrukten programmieren kann, bisweilen ist der Rückgriff auf C-Konstrukte aber immer noch die komfortablere Lösung. Beispiel: ich will Zahlen in einen String schreiben. In C macht man das mit sprintf(). In C++ gibt es dafür Stringstreams, alternativ kann aber auch wie in C sprintf() verwenden. Und in den allermeisten Fällen ist sprintf() eindeutig die praktikablere Lösung. Und so Sachen wie memcpy() und memset() sind in C++ zuweilen auch noch ganz nützlich. Sogar was die Ausgabe auf die Kommandozeile angeht, ist printf() dem cout << in einer nicht unwesentlichen Menge an Fällen überlegen.
Was sollen das denn für Fälle sein? Mir fallen nur dutzende Nachteile ein... (ein Beispiel für die Vorzüge von iostreams im letzten Beitrag im Thread https://www.computerbase.de/forum/threads/string-und-integer-verknuepfen.1226683/)

Ansonsten:
memcpy -> std::copy
memset -> std::fill
Bei beiden C++ Funktionen sehe ich den Vorteil, das man nicht sowas wie sizeof(Typ) oder so nicht vergessen kann:
float test[80];
std::fill(test, test+80, 0) vs. memset(test, 0, 80*sizeof(float))
Davon abgesehen kann man nicht nur byteweise schreiben, sondern eben bspw. floats schreiben. Und im Zusammenhang mit STL Containern wirds noch besser:
std::array<float, 80> test
std::fill(test.begin(), test.end(), 0)
Das ganze ist dann unabhängig von der konkreten Implementierung des Containers. memset/memcpy lässt sich kein generischer Code schreiben.
 
Zuletzt bearbeitet:
VikingGe schrieb:
aber böse? Wohl kaum.

Ich sag dir, warum mischen von C und C++ böse ist: Weil man schnell mit malloc/free und new/delete durcheinander kommt, und schnell irgendwelche Memory-Leaks bekommt. Zumindest gilt das für C++ Programmierer, die malloc/free nicht gewohnt sind.

Außerdem wie schon geschrieben, gibt es eben doch Inkompatibilitäten.
 
Ich sag dir, warum mischen von C und C++ böse ist: Weil man schnell mit malloc/free und new/delete durcheinander kommt, und schnell irgendwelche Memory-Leaks bekommt. Zumindest gilt das für C++ Programmierer, die malloc/free nicht gewohnt sind.

Ja gut, das ist in der Tat etwas tricky - man kann sich für solche Fälle allerdings auch ne Klasse bauen, dann mit Reference Counting arbeiten oder sonstwas, dann verschandeln einem die expliziten Aufrufe davon nicht mehr den Code. Kommt aber auch drauf an, was die jeweilige Bibliothek von einem verlangt.

Zur expliziten Speicherverwaltung sind malloc, realloc und free aber eigentlich ganz nett, wenn man weiß, wie man denn explizit C++-Objekte initialisiert und wieder zerstört. Manchmal braucht man sowas einfach der Performance wegen - aber auch hier gilt: Klasse drum und man sieht davon nicht mehr viel.
 
Sculletto schrieb:
dann bring doch mal ein Beispiel für einen C-Code vor, wo das deiner Ansicht nach so sein soll.

MSVC unterstützt nicht mal C99, ist bei C++ aber relativ aktuell, was meine Aussage schon mal bestätigt.

Natürlich gibt es auch konkrete Beispiele:
http://stackoverflow.com/questions/1201593/c-subset-of-c-where-not-examples
http://en.wikipedia.org/wiki/Compatibility_of_C_and_C++
http://david.tribble.com/text/cdiffs.htm

Die Entwicklung der Sprachen ist eben unabhängig voneinander und läuft auseinander.
 
antred schrieb:
sprintf() setzt das "What you see is what you get"-Prinzip um. Beispiel:
Code:
char szMessage[128] = "";
sprintf(szMessage, "comparing %i apples with %i pears", numApples, numPears);
vs.
Code:
std::stringstream sMessage;
sMessage << "comparing" << numApples << "apples with" << numPears << "pears";
Bei der zweiten Lösung vergisst man leicht die Leerzeichen. Anderes Beispiel:
Code:
char szMessage[256] = "";
sprintf(szMessage, "calling foo(iParam = %i, fParam1 = %.2f, fParam2 = %.4f)", iParam, fParam1, fParam2);
vs.
Code:
std::stringstream sMessage;
sMessage << "calling foo(iParam = " << iParam;
sMessage.precision(3);
sMessage << ", fParam1 = " << fParam1;
sMessage.precision(5);
sMessage << ", fParam2 = " << fParam2;
Dass man bei der zweiten Lösung schon mal schnell die schließende Klammer vergisst, ist nicht der einzige Grund, warum die erstere Lösung schneller von der Hand geht.

Selbst bei Java und C# haben die das erkannt: seit Java 5 gibt es die Funktion String.format(), die sehr stark an sprintf() angelehnt ist, bei C+ gab es immer schon die Funktion String.Format(), auch wenn diese ein eigenes System von Format-Spezifizierern verwendet.

antred schrieb:
Aber egal, was ist an std:ostringstream (für std::string-Objekte) oder std::ostrstream (für char-Arrays) nicht praktikabel?
du stellst zum zweiten Mal im selben Posting die gleiche Frage. Soll ich die Antwort noch einmal wiederholen?

antred schrieb:
Ich wüßte nicht wozu. Außer in ganz wenigen Ausnahmefällen.
Ausnahmefälle sind aber eben keine ausgeschlossenen Fälle, und müssen daher berücksichtigt werden. Beispiel: ich habe ein Array aus 32 unsigned char-Werten, die vier double-Werte codieren (etwa weil es um Messwerte handelt, die ein Messgerät anliefert, und die von dessen Treiber als unsigned char-Array bereitgestellt werden). Um daraus ein Arrays aus vier double-Werten zu machen, bietet sich memcpy an:
Code:
unsigned char pucSrc[32];
double pfDest[4];
memcpy((void*) pfDest, (void*) pucSrc, 32);
Alternativ ging auch:
Code:
unsigned char pucSrc[32];
double pfDest[4];
for (int i = 0; i < 4; i++)
{
    pfDest[i] = *((double*) &pucSrc[i*4]);
}
Das ist aber nicht nur schwerer zu lesen, sondern dürfte ebenfalls eher C-Standards als C++-Standards entsprechen.
 
Auch dieser hundertste Thread ist leider, wie die meisten andern dieser Art auch, zu einer Grundsatzdiskussion verkommen. Diese hat lange nichts mehr mit dem Thema zu tun, daher mach ich mal dicht. Tutorials wurden bereits empfohlen und es lassen sich mit Hilfe der SuFu und Google sicherlich noch viele weitere finden.
 
Status
Für weitere Antworten geschlossen.
Zurück
Oben