Seite 1 von 1

Objektinitialisierung, Programmieren mit Standardkonformität

Verfasst: Di Mär 06, 2012 10:32 am
von Xin
[edit] by fat-lobyte:
Dieses Thema wurde aus folgendem abgetrennt: http://www.proggen.org/forum/viewtopic.php?f=21&t=4870, weil sich die Diskussion zu weit vom ursprünglichen Thema entfernt hat. Die Antworten dieses Beitrags beziehen sich auf den anderen Thread.
[/edit]

fat-lobyte hat geschrieben:Hallo!
Ich möchte nur kurz von meinen Erfahrungen berichten.
Im neuen Standard gibt es einige Änderungen, wie man Objekte und Basisklassen initialisiert.

Wozu ist das überhaupt notwendig?

Betrachtet folgenden Code:

Code: Alles auswählen

rectangle        w (origin(), extents());
complex<double>  c (2.71828, 3.14159);
int              a[] = {1, 2, 3, ,4};
vector           v; for(int i;i<=4;++i) v.push_back(i);
Alle dieser vier Zeilen dienen der *Absicht* ein Objekt zu deklarieren und zu initialisieren. Diese sehen aber unterschiedlich aus, und bei Vektor muss man sogar Code für die initialisierung bereitstellen. Warum sage ich "Absicht"? ÜBERRASCHUNG!! Die erste Zeile, die zwar aussieht wie eine Variablendeklaration ist eine Funktionsdefinition!
Seit wann enthält eine Funktionsdefinition Aufrufe von anderen Funktionen/Konstruktoren?
fat-lobyte hat geschrieben: Und es verhindert die "Verschmälerung" (narrowing), Beispielsweise von integer und floating point datentypen:

Code: Alles auswählen

int x0= 7.3;	// ok: aber daten gehen verloren!
int x1 {7.3};	// error: narrowing
Das finde ich grundsätzlich gut - allerdings würde ich sie abschaffen - bzw. tue das. int x0 = 7.3 ist bei mir nicht kompilierbar. Die Schreibweise x1{7.3} stellt klar, dass hier ein Konstruktor verwendet wird.
Ich bin allerdings nicht sicher, ob ich damit glücklich würde.
Gut - das ganze hat bei mir (Genesys) eine vollkommen andere Bedeutung (nämlich den Zugriff auf das 7.3 Element).
fat-lobyte hat geschrieben:Das habe ich gemacht, und siehe da: zwei Problemchen:
1) Referenzen!

Code: Alles auswählen

struct A{};

int main()
{
    A a;
    A& a_ref{a}; // BUMM!!
}
Wieso auf einmal? Tja, hier wird aus {a} erstmal ein temporäres Objekt des Typs A erstellt, und mit a initialisiert. Dieses temp. Objekt wäre dann RValue und müsste mit einer nicht konstanten Referenz verknüpft werden. Das macht keinen Sinn: was ist eine Referenz auf ein Temporäres Objekt?
Seltsame Sache ist das, aber leider ist das so, also muss man hier weiterhin a_ref() schreiben.
Es macht in meinen Augen keinen Sinn hier ein temporäres Objekt zu erstellen. Bug oder Feature?
fat-lobyte hat geschrieben: 2) Wenn der Konstruktor eine intializer_list akzeptieren würde!
Die folgenden zwei Zeilen haben nicht den gleichen Effekt!!

Code: Alles auswählen

std::vector<int> v(100);
std::vector<int> v{100};
Wieso nicht? Nun, das betrifft zwei Konstruktoren des vector's:

Code: Alles auswählen

explicit vector(size_type n); // 1
vector(initializer_list<T>, const Allocator& = Allocator()); // 2
Die erste Zeile ruft den ersten konstruktor auf, es wird ein vektor mit 100 Elementen erstellt.
Die zweite Zeile erstellt aber ein objekt vom Typ std::initializer_list<int>, mit einem Element, nämlich 100 -> der zweite Konstruktor wird aufgerufen.
Wie entsteht die Logik, dass bei {100} eine std::initializier_list< int > erzeugt wird?
fat-lobyte hat geschrieben:Tja, das finde ich persönlich wirklich unschön aber auch damit muss ich Leben.
Ich interessiere mich sehr für solche Dinge - mit dem Unterschied, dass ich damit nicht leben muss. Ich muss mich aber damit beschäftigen, damit ich solche Szenarien verhindern kann.

Ein Link auf diesen Thread landet bei mir im Wiki.
Wir könnten uns beizeiten nochmal um Erweiterungen im C++-Tutorial unterhalten - das hier scheint mir dafür bereits hervorragend geeignet zu sein...

Re: [C++11] Uniform initialization - doch nicht so uniform?

Verfasst: Di Mär 06, 2012 11:38 am
von fat-lobyte
Xin hat geschrieben:Seit wann enthält eine Funktionsdefinition Aufrufe von anderen Funktionen/Konstruktoren?
Wenn orgin und extens typen sind, dann sieht das für den compiler so aus, als ob die Klammern "zum Spaß" dort stehen, dann kommt das mit der Funktionsdeklaration hin. Mehr info hier: http://www.informit.com/guides/content. ... seqNum=439

Xin hat geschrieben:
fat-lobyte hat geschrieben: Und es verhindert die "Verschmälerung" (narrowing), Beispielsweise von integer und floating point datentypen:

Code: Alles auswählen

int x0= 7.3;	// ok: aber daten gehen verloren!
int x1 {7.3};	// error: narrowing
Das finde ich grundsätzlich gut - allerdings würde ich sie abschaffen - bzw. tue das. int x0 = 7.3 ist bei mir nicht kompilierbar.
Das geht in C++ nicht, da man kompatibilität mit C wahren will. Außerdem weiß ich nicht ob ich das gut finden würde das ganz abzuschaffen... Jetzt hat man beide möglichkeiten, da muss man eine nicht verbieten.
Xin hat geschrieben:
fat-lobyte hat geschrieben:Das habe ich gemacht, und siehe da: zwei Problemchen:
1) Referenzen!

Code: Alles auswählen

struct A{};

int main()
{
    A a;
    A& a_ref{a}; // BUMM!!
}
Wieso auf einmal? Tja, hier wird aus {a} erstmal ein temporäres Objekt des Typs A erstellt, und mit a initialisiert. Dieses temp. Objekt wäre dann RValue und müsste mit einer nicht konstanten Referenz verknüpft werden. Das macht keinen Sinn: was ist eine Referenz auf ein Temporäres Objekt?
Seltsame Sache ist das, aber leider ist das so, also muss man hier weiterhin a_ref() schreiben.
Es macht in meinen Augen keinen Sinn hier ein temporäres Objekt zu erstellen. Bug oder Feature?
Gut Frage. Ich tippe mal auf Feature, denn:

Code: Alles auswählen

struct Punkt
{
    Punkt (int x, int y) : _x{x}, _y{y} {}

    int _x, _y;
};

struct Rechteck 
{
    Rechteck(const Punkt& lo, const Punkt& ru) : _lo{lo}, _ru{ru} {}
    Punkt _lo, _ru;
};

Rechteck r{Punkt{1, 2}, Punkt{3, 4}};
Wäre sonst nicht möglich. Übrigens: man hätte auch Rechteck r{{1,2}, {3, 4}}; schreiben können. Ich nenne das den "Du weißt eh was ich meine"-Konstruktor :)
Xin hat geschrieben:Wie entsteht die Logik, dass bei {100} eine std::initializier_list< int > erzeugt wird?
Man kan in C++11 Vektoren und andere Container direkt bei ihrer deklaration initialisieren:

Code: Alles auswählen

std::vector<int> v = {1, 2, 3, 4, 5};
Macht die Sache sehr hübsch, Meinermeinung nach. Das funktioniert dann über ein temporäres Objekt des Typs std::initializer_list<int>, das dem Konstruktor von vector<> übergeben wird.

Xin hat geschrieben:
fat-lobyte hat geschrieben:Tja, das finde ich persönlich wirklich unschön aber auch damit muss ich Leben.
Ich interessiere mich sehr für solche Dinge - mit dem Unterschied, dass ich damit nicht leben muss. Ich muss mich aber damit beschäftigen, damit ich solche Szenarien verhindern kann.
C++ ist eine sehr sehr mächtige Sprache, die aber auch kompatibilität mit C wahren muss - da kanns schon mal passieren, das sich etwas unangenehm anfühlt.
Denkst du, du könntest eine Ähnlich mächtige Sprache schaffen, die keine derartigen Probleme hat? Da gibts interaktionen der einzelnen Elemente, auf die man als einzelne Person nie draufkommen würde - da braucht man viele, viele Augenpaare.
Xin hat geschrieben:Ein Link auf diesen Thread landet bei mir im Wiki.
Ähem... <werbung>Wie wärs dann noch mit diesem Thread hier: http://www.proggen.org/forum/viewtopic. ... 2</werbung>
Xin hat geschrieben:Wir könnten uns beizeiten nochmal um Erweiterungen im C++-Tutorial unterhalten - das hier scheint mir dafür bereits hervorragend geeignet zu sein...
Hm, das ist so ne Sache. Das was du "Erweiterung" nennst, betrachte ich eigentlich als ne ziemlich neue Sprache - diese kleinen "Erweiterungen" ändern einfach "wie man Dinge macht", also vorhandene Praktiken. Workarounds die man früher hatte werden Obsolet (konstruktor vs. funktionsdekl.), gewisse Dinge werden vieel einfacher (auto, range-based-for loop). Ich bin mir nicht sicher obs so viel Sinn macht, auf ein bestehendes Tutorial die neuen Features einfach drüberzustülpen.

Re: [C++11] Uniform initialization - doch nicht so uniform?

Verfasst: Di Mär 06, 2012 12:07 pm
von Xin
fat-lobyte hat geschrieben:
Xin hat geschrieben:Seit wann enthält eine Funktionsdefinition Aufrufe von anderen Funktionen/Konstruktoren?
Wenn orgin und extens typen sind, dann sieht das für den compiler so aus, als ob die Klammern "zum Spaß" dort stehen, dann kommt das mit der Funktionsdeklaration hin. Mehr info hier: http://www.informit.com/guides/content. ... seqNum=439
Wenn da Klammern hinterstehen, dann nicht zum Spaß, sondern weil man den Standard-Konstruktor rufen will.
fat-lobyte hat geschrieben:
Xin hat geschrieben:
fat-lobyte hat geschrieben: Und es verhindert die "Verschmälerung" (narrowing), Beispielsweise von integer und floating point datentypen:

Code: Alles auswählen

int x0= 7.3;	// ok: aber daten gehen verloren!
int x1 {7.3};	// error: narrowing
Das finde ich grundsätzlich gut - allerdings würde ich sie abschaffen - bzw. tue das. int x0 = 7.3 ist bei mir nicht kompilierbar.
Das geht in C++ nicht, da man kompatibilität mit C wahren will. Außerdem weiß ich nicht ob ich das gut finden würde das ganz abzuschaffen... Jetzt hat man beide möglichkeiten, da muss man eine nicht verbieten.
Man kann auch das Spracheverhalten ändern. Erst mit Warnings, dann mit Fehlern und einem Schalter, der den Compiler in einen Kompatiblitätsmodus versetzt.

Kompatiblität ist gut, aber man sollte sich durchaus bewusst sein, dass Quellen, die vor 30 Jahren geschrieben wurden zwischenzeitlich vielleicht nochmal angepackt werden müssen.
fat-lobyte hat geschrieben:
Xin hat geschrieben: Es macht in meinen Augen keinen Sinn hier ein temporäres Objekt zu erstellen. Bug oder Feature?
Gut Frage. Ich tippe mal auf Feature, denn:

Code: Alles auswählen

struct Punkt
{
    Punkt (int x, int y) : _x{x}, _y{y} {}

    int _x, _y;
};

struct Rechteck 
{
    Rechteck(const Punkt& lo, const Punkt& ru) : _lo{lo}, _ru{ru} {}
    Punkt _lo, _ru;
};

Rechteck r{Punkt{1, 2}, Punkt{3, 4}};
Wäre sonst nicht möglich. Übrigens: man hätte auch Rechteck r{{1,2}, {3, 4}}; schreiben können. Ich nenne das den "Du weißt eh was ich meine"-Konstruktor :)
Bei mir heißt das Erwartungshaltung.
fat-lobyte hat geschrieben:
Xin hat geschrieben:Wie entsteht die Logik, dass bei {100} eine std::initializier_list< int > erzeugt wird?
Man kan in C++11 Vektoren und andere Container direkt bei ihrer deklaration initialisieren:

Code: Alles auswählen

std::vector<int> v = {1, 2, 3, 4, 5};
Macht die Sache sehr hübsch, Meinermeinung nach. Das funktioniert dann über ein temporäres Objekt des Typs std::initializer_list<int>, das dem Konstruktor von vector<> übergeben wird.
Ich bin überhaupt kein Freund von temporären Objekten.
fat-lobyte hat geschrieben:Denkst du, du könntest eine Ähnlich mächtige Sprache schaffen, die keine derartigen Probleme hat? Da gibts interaktionen der einzelnen Elemente, auf die man als einzelne Person nie draufkommen würde - da braucht man viele, viele Augenpaare.
Und den Mut, wieder ein paar Schritte zurück zu gehen, wenn man auf dem Holzweg war.
fat-lobyte hat geschrieben:
Ein Link auf diesen Thread landet bei mir im Wiki.
Ähem... <werbung>Wie wärs dann noch mit diesem Thread hier: http://www.proggen.org/forum/viewtopic. ... 2</werbung>
Ich habe mir heute ein Buch zu C++11 bestellt. Mit etwas Glück kommt es rechtzeitig an, dass ich es im Hotel lesen kann. Da kann man ja sonst nicht viel sinnvolles tun, also optimal, um ein Buch zu lesen... wenn's rechtzeitig da ist. :-)
fat-lobyte hat geschrieben:Hm, das ist so ne Sache. Das was du "Erweiterung" nennst, betrachte ich eigentlich als ne ziemlich neue Sprache - diese kleinen "Erweiterungen" ändern einfach "wie man Dinge macht", also vorhandene Praktiken.
Mag sein, dann schreiben wir in Zukunft C/C++/C++11.

Es entsteht nicht immer eine neue Sprache - schon alleine wegen der gewollten Kompatiblität.
Dass man in C++ "Objektorientiert" programmiert und die Fachwelt ein popliges Designpattern zum Paradigma verklärt, dass sich aber irgendwie nicht recht in die anderen Paradigmen einfinden will (weil es eben kein Paradigma ist), macht aus C++ keine neue Sprache, sondern ein C mit zusätzlichen Funktionen.
Das ist Evolution. Der Mensch ist auch nur ein Säugetier, auch wenn "nach dem Ebenbild Gottes" vielleicht charmanter klingt (besonders, wenn man sich das Nachmittagsprogramm diverser Privatsender ansieht).
fat-lobyte hat geschrieben:Workarounds die man früher hatte werden Obsolet (konstruktor vs. funktionsdekl.), gewisse Dinge werden vieel einfacher (auto, range-based-for loop). Ich bin mir nicht sicher obs so viel Sinn macht, auf ein bestehendes Tutorial die neuen Features einfach drüberzustülpen.
Das müssen wir dann Feature für Feature entscheiden.
Es ist ja auch eine zeitliche Frage: Was nutzt es ein Feature groß hervorzuheben, dass z.B. das aktuelle Visual Studio gar nicht versteht. Da muss das Feature aus dem Tutorial heraus und als Artikel dazu: "Wenn Du einen aktuellen Compiler hast, dann siehe >>Artikel<<". Ich kann von einem interessierten Anfänger nicht verlangen, sich den aktuellen GCC selbst zu kompilieren. Der wird sich daran erinnern, dass ihm jeder gesagt hat, C++ ist zu kompliziert und das bestätigt finden.

Fakt ist, zurzeit bist Du hier der C++11-King hier und Du wolltest damals mit mir das C++-Tutorial voranbringen. Bzgl. der Deines C++-King-Titels werde ich Dir den auf kurz oder lang wieder streitig machen. C++11 muss ins Wiki und kommt ins Wiki. Im Idealfall für's Wiki setzen wir uns zusammen hin und planen das gemeinsam.

Im C Tutorial muss ich noch drei, vier Artikel hinzufügen, und den alten Index ausmisten. Dann ist das durch und sauber.
Dann gehe ich zum C++-Tutorial und werde da die Baustelle schließen, wäre gut, wenn ich dann zumindest jemand habe, mit dem ich den Aufbau diskutieren kann. Schreiben kann ich das schon.

Grundsätzlich würde ich mich aber auch freuen, wenn Du GIT und GDB fortsetzen könntest.

Re: [C++11] Uniform initialization - doch nicht so uniform?

Verfasst: Di Mär 06, 2012 10:25 pm
von fat-lobyte
Xin hat geschrieben:
fat-lobyte hat geschrieben:Wenn orgin und extens typen sind, dann sieht das für den compiler so aus, als ob die Klammern "zum Spaß" dort stehen, dann kommt das mit der Funktionsdeklaration hin. Mehr info hier: http://www.informit.com/guides/content. ... seqNum=439
Wenn da Klammern hinterstehen, dann nicht zum Spaß, sondern weil man den Standard-Konstruktor rufen will.
Jetzt ok, dann sind es zwei Funktionszeiger auf Funktionen die keine Argumente nehmen und origin/extent-Objekte zurückgeben. Hast du das Problem ehrlich noch nie gehabt?
Xin hat geschrieben:Man kann auch das Spracheverhalten ändern. Erst mit Warnings, dann mit Fehlern und einem Schalter, der den Compiler in einen Kompatiblitätsmodus versetzt.

Kompatiblität ist gut, aber man sollte sich durchaus bewusst sein, dass Quellen, die vor 30 Jahren geschrieben wurden zwischenzeitlich vielleicht nochmal angepackt werden müssen.
Das sehe ich ähnlich, ewig Ballast mitzuführen ist keine gute Sache. Die Argumentation des Standardkommittees (vor allem Bjarne Stroustrup) ist, dass man "Dialektbildung" und "Zersplitterung" der Community vermeiden will, die entstehen könnte wenn man ein "veraltetes", aber dennoch verbreitetes Feature entfernt.
Xin hat geschrieben:Bei mir heißt das Erwartungshaltung.
Da sehe ich kein Problem. Der Compiler weiß was gemeint ist, ich weiß was gemeint ist, warum soll ich dann noch Prosa schreiben?
Xin hat geschrieben:Ich bin überhaupt kein Freund von temporären Objekten.
Ich bin ein großer Freund davon.
Hier ein bisschen Code aus der Zeit, in der mich Windows noch interessiert hat:

Code: Alles auswählen

// A struct that represents a window class
	WNDCLASSEX wndclass;	
	
	/* This is a variable containing the style flags for the Window Class. */
	UINT wnd_style = CS_HREDRAW | CS_VREDRAW;
	
	
	/* These values will be handed over to the CreateWindowEx() function. */
	int start_x = CW_USEDEFAULT;
	int start_y = CW_USEDEFAULT;	
	
	

	/* Filling wndclass Structure */
	wndclass.cbSize = sizeof (WNDCLASSEX);
	wndclass.style = wnd_style;
	wndclass.lpfnWndProc = wndProc;
	wndclass.cbClsExtra = 0;
	wndclass.cbWndExtra = 0;
	wndclass.hInstance = hInstance;
	wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
	wndclass.hCursor = LoadCursor (NULL, IDC_ARROW);
	wndclass.hbrBackground = (HBRUSH) GetStockObject (LTGRAY_BRUSH);
	wndclass.lpszMenuName = NULL;
	wndclass.lpszClassName = szAppName;
	wndclass.hIconSm =  LoadIcon (NULL, IDI_APPLICATION);
	
	
	// register window class
	registerWndClass(&wndclass);
	
	// create a window
	create(0, 
		szAppName,
		title,
		WS_OVERLAPPEDWINDOW | WS_VISIBLE,
		start_x, start_y,
		width, height,
		NULL,
		NULL,
		hInstance,
		0);
Das ist C. Hier wurden keine temporären Objekte angelegt. Nur wieso nicht?? Warum muss ich jedes futzelchen Code definieren? Warum muss ich extra Variablen am Stack anlegen, die dann sowieso gleich gefressen werden, und in anderen Objekten verschwinden? Wieso hin und her kopieren?
1. Mit temporären Objekten und Move-Semantik kann ich ausdrücken was ich mir Denke, nämlich: Erstelle ein Rechteck aus zwei Punkten. Nicht: Erstelle einen Punkt. Erstelle noch einen. Erstelle aus den Zweien ein Rechteck. Vergiss die beiden Punkte wieder.
2. Es sollte in einer Bibliothek *immer* einen einfachen Weg geben. Wenn jemand was genau bestimmen will, dafür kann man Overloads bereitstellen, default-Argumente, oder was auch immer. Aber einen offensichtlichen und einfachen weg muss es geben.
Und den Mut, wieder ein paar Schritte zurück zu gehen, wenn man auf dem Holzweg war.
Ein Ambitioniertes Projekt :-)
Xin hat geschrieben:Ich habe mir heute ein Buch zu C++11 bestellt. Mit etwas Glück kommt es rechtzeitig an, dass ich es im Hotel lesen kann. Da kann man ja sonst nicht viel sinnvolles tun, also optimal, um ein Buch zu lesen... wenn's rechtzeitig da ist. :-)
Sowas gibts schon?? Sollte man mit Büchern zu "existing Practice" nicht warten, bis die Praxis tatsächlich existiert?
fat-lobyte hat geschrieben:Hm, das ist so ne Sache. Das was du "Erweiterung" nennst, betrachte ich eigentlich als ne ziemlich neue Sprache - diese kleinen "Erweiterungen" ändern einfach "wie man Dinge macht", also vorhandene Praktiken.
Mag sein, dann schreiben wir in Zukunft C/C++/C++11.

Es entsteht nicht immer eine neue Sprache - schon alleine wegen der gewollten Kompatiblität.
Dass man in C++ "Objektorientiert" programmiert und die Fachwelt ein popliges Designpattern zum Paradigma verklärt, dass sich aber irgendwie nicht recht in die anderen Paradigmen einfinden will (weil es eben kein Paradigma ist), macht aus C++ keine neue Sprache, sondern ein C mit zusätzlichen Funktionen.
Das ist Evolution. Der Mensch ist auch nur ein Säugetier, auch wenn "nach dem Ebenbild Gottes" vielleicht charmanter klingt (besonders, wenn man sich das Nachmittagsprogramm diverser Privatsender ansieht).
Xin hat geschrieben:Das müssen wir dann Feature für Feature entscheiden.
Es ist ja auch eine zeitliche Frage: Was nutzt es ein Feature groß hervorzuheben, dass z.B. das aktuelle Visual Studio gar nicht versteht.
Da muss das Feature aus dem Tutorial heraus und als Artikel dazu: "Wenn Du einen aktuellen Compiler hast, dann siehe >>Artikel<<". Ich kann von einem interessierten Anfänger nicht verlangen, sich den aktuellen GCC selbst zu kompilieren. Der wird sich daran erinnern, dass ihm jeder gesagt hat, C++ ist zu kompliziert und das bestätigt finden.
Da hast du recht, das ist inakzeptabel. Andererseits: willst du wirklich Artikel schreiben, die ein Ablaufdatum haben? Ich persönlich finde das ziemlich frustrierend. Ich schreibe lieber in der Zukunft, und impliziere, dass der Leser einen Standardkonformen Compiler hat. Ich weiß nicht wie viele Leser das C++-Tutorial hat, aber die wenigen, die dabei "draufgehen" bis in ungefähr einem Jahr die Compiler nachgerüstet haben würde ich in Kauf nehmen.
Fakt ist, zurzeit bist Du hier der C++11-King hier und Du wolltest damals mit mir das C++-Tutorial voranbringen. Bzgl. der Deines C++-King-Titels werde ich Dir den auf kurz oder lang wieder streitig machen.
Sehr gerne. Ich habe auch oft Null plan, und hätte gerne jemanden den ich fragen könnte. Im moment siehts hier dünn aus, was die neuen Sachen betrifft...
C++11 muss ins Wiki und kommt ins Wiki. Im Idealfall für's Wiki setzen wir uns zusammen hin und planen das gemeinsam.

Im C Tutorial muss ich noch drei, vier Artikel hinzufügen, und den alten Index ausmisten. Dann ist das durch und sauber.
Dann gehe ich zum C++-Tutorial und werde da die Baustelle schließen, wäre gut, wenn ich dann zumindest jemand habe, mit dem ich den Aufbau diskutieren kann. Schreiben kann ich das schon.
Klingt nach nem Plan.

Re: [C++11] Uniform initialization - doch nicht so uniform?

Verfasst: Mi Mär 07, 2012 11:34 am
von Xin
fat-lobyte hat geschrieben:
Xin hat geschrieben:
fat-lobyte hat geschrieben:Wenn orgin und extens typen sind, dann sieht das für den compiler so aus, als ob die Klammern "zum Spaß" dort stehen, dann kommt das mit der Funktionsdeklaration hin. Mehr info hier: http://www.informit.com/guides/content. ... seqNum=439
Wenn da Klammern hinterstehen, dann nicht zum Spaß, sondern weil man den Standard-Konstruktor rufen will.
Jetzt ok, dann sind es zwei Funktionszeiger auf Funktionen die keine Argumente nehmen und origin/extent-Objekte zurückgeben. Hast du das Problem ehrlich noch nie gehabt?
Wenn es Funktionszeiger sind, dann macht das für mich erstmal keinen Unterschied. Die Funktionen, die hier referenziert gerufen wird, liefert Werte und Datentypen zurück und die bestimmen, welcher Konstruktor von rectangle gerufen wird, um w zu initialisieren.
=> keine Funktionsdeklaration.
=> kein Problem

Entweder sehe ich Dein Problem nicht oder es gibt keins!?
fat-lobyte hat geschrieben:
Xin hat geschrieben:Man kann auch das Spracheverhalten ändern. Erst mit Warnings, dann mit Fehlern und einem Schalter, der den Compiler in einen Kompatiblitätsmodus versetzt.

Kompatiblität ist gut, aber man sollte sich durchaus bewusst sein, dass Quellen, die vor 30 Jahren geschrieben wurden zwischenzeitlich vielleicht nochmal angepackt werden müssen.
Das sehe ich ähnlich, ewig Ballast mitzuführen ist keine gute Sache. Die Argumentation des Standardkommittees (vor allem Bjarne Stroustrup) ist, dass man "Dialektbildung" und "Zersplitterung" der Community vermeiden will, die entstehen könnte wenn man ein "veraltetes", aber dennoch verbreitetes Feature entfernt.
Tjoah, ich denke, da haben wir was, was Stroustrup und mich sehr deutlich unterscheidet. ^^
fat-lobyte hat geschrieben:
Xin hat geschrieben:Ich bin überhaupt kein Freund von temporären Objekten.
Ich bin ein großer Freund davon.
Hier ein bisschen Code aus der Zeit, in der mich Windows noch interessiert hat:
...

Das ist C. Hier wurden keine temporären Objekte angelegt. Nur wieso nicht?? Warum muss ich jedes futzelchen Code definieren? Warum muss ich extra Variablen am Stack anlegen, die dann sowieso gleich gefressen werden, und in anderen Objekten verschwinden? Wieso hin und her kopieren?
Du legst temporäre Objekte an, um sie zu kopieren.

Das ist nichts anderes als das wofür Du gerade argumentierst.
Weil ich das Hin- und Herkopieren nicht gut finde - vor allem weil es Zeit kostet - bin ich mehr für andere Methoden.
Ich bevorzuge einen zweistufigen Aufbau von Objekten: Das Fundament des Objektes wird aufgebaut (Speicher reserviert), anschließend beschickt man die Daten. Statt einen Punkt temporär zu konstruieren und an den Konstruktor zu überreichen, konstruiert man ihn in das aufzubauende Objekt. Am Ende validiert man das neue Objekt oder lässt es, falls es ein Problem gab.
fat-lobyte hat geschrieben:
Und den Mut, wieder ein paar Schritte zurück zu gehen, wenn man auf dem Holzweg war.
Ein Ambitioniertes Projekt :-)
Ich weiß.

Höre ich häufiger. Üblicherweise als Umschreibung für zu aufwendig, nicht umsetzbar.
fat-lobyte hat geschrieben:
Xin hat geschrieben:Ich habe mir heute ein Buch zu C++11 bestellt. Mit etwas Glück kommt es rechtzeitig an, dass ich es im Hotel lesen kann. Da kann man ja sonst nicht viel sinnvolles tun, also optimal, um ein Buch zu lesen... wenn's rechtzeitig da ist. :-)
Sowas gibts schon?? Sollte man mit Büchern zu "existing Practice" nicht warten, bis die Praxis tatsächlich existiert?
Wird schwierig, wenn sich keiner die Theorie aneignet.
fat-lobyte hat geschrieben:Andererseits: willst du wirklich Artikel schreiben, die ein Ablaufdatum haben? Ich persönlich finde das ziemlich frustrierend.
Ja, will ich.

Mein erstes C-Tutorial hier ist abgelaufen. Nun haben wir ein (hoffentlich) besseres. Das Feedback auf das neue Tutorial ist recht gut. Ich bekam damals auch positives Feedback auf das alte - lange bevor es proggen.org gab. Das Feedback dieses Tutorials auf proggen.org war quasi nicht vorhanden, obwohl es das meistgelesene Tutorial hier ist.

Es gibt kein 'gut für alle Zeiten'. Ich habe keine Ahnung, was morgen kommt. Aber es gibt ein erreichbares "Gut" in der Gegenwart. Ich kann in der Gegenwart darauf hinweisen, was man in der Zukunft gut machen könnte. Und wenn das dann jeder macht, dann ist der Artikel veraltet.
Vor allem hat er seinen Zweck erfüllt.

Ich finde es sehr motivierend, wenn ein Artikel 2 Jahre lang Leute sehr gut unterstützt und dann geändert werden muss, um weitere 2 Jahre Leute unterstützen zu können. Darum haben wir ein Wiki - um die Texte der Gegenwart anpassen zu können.
fat-lobyte hat geschrieben:Ich schreibe lieber in der Zukunft, und impliziere, dass der Leser einen Standardkonformen Compiler hat. Ich weiß nicht wie viele Leser das C++-Tutorial hat, aber die wenigen, die dabei "draufgehen" bis in ungefähr einem Jahr die Compiler nachgerüstet haben würde ich in Kauf nehmen.
Damit erreichst Du aber nur diejenigen, die sich das wirklich geben müssen. Und die können C++ dann in der Regel schon und wollen einfach nur noch mehr lernen.

Es gibt noch keine standardkonformen C++-Compiler. Sollten Standards also nie umgesetzt werden, schreibst Du über Dinge, die in der Realität nicht vorkommen. Sogar den alten Standard unterstützt kaum einer vollständig.
fat-lobyte hat geschrieben:
Im C Tutorial muss ich noch drei, vier Artikel hinzufügen, und den alten Index ausmisten. Dann ist das durch und sauber.
Dann gehe ich zum C++-Tutorial und werde da die Baustelle schließen, wäre gut, wenn ich dann zumindest jemand habe, mit dem ich den Aufbau diskutieren kann. Schreiben kann ich das schon.
Klingt nach nem Plan.
Machst Du bei GDB/GIT weiter?

Re: [C++11] Uniform initialization - doch nicht so uniform?

Verfasst: Mi Mär 07, 2012 12:28 pm
von fat-lobyte
Xin hat geschrieben:Entweder sehe ich Dein Problem nicht oder es gibt keins!?

Code: Alles auswählen

struct B {
    B() {}
};

struct A {
    A(B b) { }    
    void myMethod() {}
};

int main()
{
    A a(B());    
    a.myMethod();
}
Quizzfrage: was tut die Zeile A a(B()); ? Nach der Antwort kompiliere bitte dieses Programm.
Xin hat geschrieben:Du legst temporäre Objekte an, um sie zu kopieren.
Eben nicht! Das musste ich bisher, jetzt kann ich sie statt zu kopieren in das Objekt "hineinmoven".
Xin hat geschrieben:Weil ich das Hin- und Herkopieren nicht gut finde - vor allem weil es Zeit kostet -
Es kostet zwar Zeit, mit RValue references und richtig geschriebenen Konstruktoren nur mehr wenig. Außerdem sollten Compiler den Overhead erkennen und wegoptimieren.
Xin hat geschrieben:Ich bevorzuge einen zweistufigen Aufbau von Objekten: Das Fundament des Objektes wird aufgebaut (Speicher reserviert), anschließend beschickt man die Daten.
Das mag ich gar nicht. Ich will "Zombiobjekte" vermeiden. Mir gehts drum im Code das auszudrücken was ich denke.
Ich denke: mach hier ein Rechteck aus diesen Punkten. Wenns Probleme gibt sag bescheid (= Exception).
Was ich nicht denke: Mach hier bitte ein bisschen Speicher, dann setzen wir mal den einen Punkt, dann den anderen, dann musst du mir noch sagen ob alles in Ordnung war, und wenn ja dann machen wir weiter. Das finde ich extrem unschön.

Objektorientiert heißt für mich, dass ich ein Objekt erstelle, und es nach der initialisierung sofort bereit ist. Wenn ich zum Code nach der deklaration komme (und es keine Exception gab), dann ist das Objekt fertig und ich kanns verwenden. Das ist genau die statische Garantie, die ich von C++ erwarte.
Xin hat geschrieben:Höre ich häufiger. Üblicherweise als Umschreibung für zu aufwendig, nicht umsetzbar.
Du hasts erfasst. C++ ist sehr lange gewachsen, und nur ganz am Anfang durch die Hand eines einzigen Mannes. Es stecken viele, viele Arbeitstunden dahinter, von vielen ziemlich intelligenten Leuten. Dann stecken noch viel viel viel mehr (evtl. weniger intelligente) Augenpaare dahinter, die es verwendet haben und Probleme aufgezeigt haben. Dass du in deiner Lebenszeit etwas auf die Beine stellst, das konkurrenzfähig ist, und auch noch "Besser" sein soll als C++ glaube ich erst wenn ichs sehe :-). Nicht falsch verstehen - ich lass mich sehr gerne überraschen.

Aber hier gleich mal mein Hauptkriterium für eine gute Sprache:
Ich will ausdrücken können was ich denke. Die Konzepte will ich mit möglichst wenig Syntaktischem Overhead aufs papier bringen. Was ich nicht will ist es mit dem Compiler zu spielen, damit er tut was ich will oder mich in die Hardware einarbeiten wo ich für ein Paar Optimierungen den "Kopf brechen" muss - das soll verdammt noch mal der Compiler machen, dafür gibts ihn ja.
C++ mit seinen Templates ist (zumindest auf der Bibliotheks-Anwenderseite) verdammt gut darin. Kannst du das toppen?
fat-lobyte hat geschrieben:Es gibt kein 'gut für alle Zeiten'. Ich habe keine Ahnung, was morgen kommt. Aber es gibt ein erreichbares "Gut" in der Gegenwart. Ich kann in der Gegenwart darauf hinweisen, was man in der Zukunft gut machen könnte. Und wenn das dann jeder macht, dann ist der Artikel veraltet.
Hm, da hast du vielleicht recht. Da sollte ich vl. meine Einstellung dazu ändern. In dem konkreten Fall würde sichs auszahlen auf die Zukunft zu setzen, denn sowohl beim GCC als auch bei Clang stehen da schon verdammt viele "Ja"'s bei den Features. Visual Studio hinkt noch nach, es wurde aber versprochen dass in den nächsten 1-2 Jahren auch außerhalb der Visual Studio Major-releases nachzurüsten.
GCC-4.6 hat schon genug, dass man echt und Effektiv Programmieren kann. 4.7 sollte nicht weit weg sein.
Xin hat geschrieben:Es gibt noch keine standardkonformen C++-Compiler. Sollten Standards also nie umgesetzt werden, schreibst Du über Dinge, die in der Realität nicht vorkommen. Sogar den alten Standard unterstützt kaum einer vollständig.
Das interessiert mich nicht :-) Mir gehts hier um keine Zertifizierung, dass ein Compiler alles vollkommen unterstützt. Wenn ich sage "Standardkonform", dann meine ich nicht das als Typ "bool", sondern als Prozentueller Anteil, aka "Wie viel neues Zeugs kann der Compiler denn schon?". Und da siehts nicht so schlecht aus.
Xin hat geschrieben:Machst Du bei GDB/GIT weiter?
Ja, kann ich machen. Was ich nicht machen kann ist dir ein Versprechen abzugeben wann das geschieht. Leider.

Re: [C++11] Uniform initialization - doch nicht so uniform?

Verfasst: Mi Mär 07, 2012 2:29 pm
von Xin
fat-lobyte hat geschrieben:
Xin hat geschrieben:Entweder sehe ich Dein Problem nicht oder es gibt keins!?

Code: Alles auswählen

struct B {
    B() {}
};

struct A {
    A(B b) { }    
    void myMethod() {}
};

int main()
{
    A a(B());    
    a.myMethod();
}
Quizzfrage: was tut die Zeile A a(B()); ? Nach der Antwort kompiliere bitte dieses Programm.
Sie erzeugt ein temporäres Objekt vom Typ B const, welches auf den Parameter b vom Typ B kopiert wird.
Optimiert: sie konstruiert den Parameter b vom Typ B.

Und bevor ich das jetzt kompiliere, weiß ich, dass das falsch ist, weil es das beliebte Beispiel ist, um das Chaos von Variablendeklarationen mit dem Standard-Konstruktor, bzw. verkorksten Funktionszeigerdefinitionen. :-)

Code: Alles auswählen

    A a=B();
oder bei explicit:
    A a = A(B());    
Wirklich nicht schön - aber nicht wirklich ein Problem.

Das Problem - die Funktionszeigerdeklarationen, die jeder ja jeden Tag benötigt, könnte man durch einen Kompatiblitätsmodus aus C herausoperieren. Macht man aber nicht.
Stattdessen bevorzugt man, dass man laufend diese Quizfrage gestellt bekommt.
fat-lobyte hat geschrieben:
Xin hat geschrieben:Du legst temporäre Objekte an, um sie zu kopieren.
Eben nicht! Das musste ich bisher, jetzt kann ich sie statt zu kopieren in das Objekt "hineinmoven".
Und das konntest Du vorher nicht?

Hier wird es schwierig, denn was ein Compiler aus einer Initialisierungsliste macht ist nicht zwangsläufig das, was die Sprache semantisch hergibt. Sich darauf zu verlassen, dass der Compiler das Problem löst/wegoptimiert, obwohl die Sprache das semantisch gar nicht ausdrückt, kann zu interessanten Unterschieden zwischen Debug und Releaseversion führen.
Ich sehe hier keinen "Move".
fat-lobyte hat geschrieben:
Xin hat geschrieben:Weil ich das Hin- und Herkopieren nicht gut finde - vor allem weil es Zeit kostet -
Es kostet zwar Zeit, mit RValue references und richtig geschriebenen Konstruktoren nur mehr wenig. Außerdem sollten Compiler den Overhead erkennen und wegoptimieren.
Ich denke, damit sollten sie vorsichtig sein, wenn ich das nicht im Quelltext verlange.
fat-lobyte hat geschrieben:
Xin hat geschrieben:Ich bevorzuge einen zweistufigen Aufbau von Objekten: Das Fundament des Objektes wird aufgebaut (Speicher reserviert), anschließend beschickt man die Daten.
Das mag ich gar nicht. Ich will "Zombiobjekte" vermeiden. Mir gehts drum im Code das auszudrücken was ich denke.
Ich denke: mach hier ein Rechteck aus diesen Punkten. Wenns Probleme gibt sag bescheid (= Exception).
Was ich nicht denke: Mach hier bitte ein bisschen Speicher, dann setzen wir mal den einen Punkt, dann den anderen, dann musst du mir noch sagen ob alles in Ordnung war, und wenn ja dann machen wir weiter. Das finde ich extrem unschön.
Es ist gradlinig und hat den minimalsten Aufwand.
fat-lobyte hat geschrieben:Objektorientiert heißt für mich, dass ich ein Objekt erstelle, und es nach der initialisierung sofort bereit ist. Wenn ich zum Code nach der deklaration komme (und es keine Exception gab), dann ist das Objekt fertig und ich kanns verwenden. Das ist genau die statische Garantie, die ich von C++ erwarte.
Ich werde wohl eine Zwischenstufe einlegen: Existierende Objekte, die nicht initialisiert sind.
fat-lobyte hat geschrieben:
Xin hat geschrieben:Höre ich häufiger. Üblicherweise als Umschreibung für zu aufwendig, nicht umsetzbar.
Du hasts erfasst. C++ ist sehr lange gewachsen, und nur ganz am Anfang durch die Hand eines einzigen Mannes. Es stecken viele, viele Arbeitstunden dahinter, von vielen ziemlich intelligenten Leuten. Dann stecken noch viel viel viel mehr (evtl. weniger intelligente) Augenpaare dahinter, die es verwendet haben und Probleme aufgezeigt haben. Dass du in deiner Lebenszeit etwas auf die Beine stellst, das konkurrenzfähig ist, und auch noch "Besser" sein soll als C++ glaube ich erst wenn ichs sehe :-). Nicht falsch verstehen - ich lass mich sehr gerne überraschen.
Ich bin mir des Problems bewusst.
Mit ein Grund, warum ich auch auf Änderungen und Dialekte anders bewerte als Stroustrup.
fat-lobyte hat geschrieben:Aber hier gleich mal mein Hauptkriterium für eine gute Sprache:
Ich will ausdrücken können was ich denke. Die Konzepte will ich mit möglichst wenig Syntaktischem Overhead aufs papier bringen. Was ich nicht will ist es mit dem Compiler zu spielen, damit er tut was ich will oder mich in die Hardware einarbeiten wo ich für ein Paar Optimierungen den "Kopf brechen" muss - das soll verdammt noch mal der Compiler machen, dafür gibts ihn ja.
C++ mit seinen Templates ist (zumindest auf der Bibliotheks-Anwenderseite) verdammt gut darin. Kannst du das toppen?
Ja.
fat-lobyte hat geschrieben:
Xin hat geschrieben:Es gibt kein 'gut für alle Zeiten'. Ich habe keine Ahnung, was morgen kommt. Aber es gibt ein erreichbares "Gut" in der Gegenwart. Ich kann in der Gegenwart darauf hinweisen, was man in der Zukunft gut machen könnte. Und wenn das dann jeder macht, dann ist der Artikel veraltet.
Hm, da hast du vielleicht recht. Da sollte ich vl. meine Einstellung dazu ändern. In dem konkreten Fall würde sichs auszahlen auf die Zukunft zu setzen, denn sowohl beim GCC als auch bei Clang stehen da schon verdammt viele "Ja"'s bei den Features. Visual Studio hinkt noch nach, es wurde aber versprochen dass in den nächsten 1-2 Jahren auch außerhalb der Visual Studio Major-releases nachzurüsten.
GCC-4.6 hat schon genug, dass man echt und Effektiv Programmieren kann. 4.7 sollte nicht weit weg sein.
Du und ich benutzen Linux. Wenn jemand C oder C++ lernen möchte, dann ist sein primäres Ziel C und C++ zu lernen. Eventuell unter Windows.
Ich benutze aktuell den GCC 4.4. Meine Programme kompilieren auch mit VC2010.
In der Firma habe ich das Problem, dass einige Programmteile mit VC6 kompilieren müssen. Das ist schon leicht extrem, aber alte Compiler unterstützen zu müssen ist in Firmen ein recht übliches Problem.
Es ist gut, wenn Du mit Blick auf die Zukunft schreibst. Aber man darf die Vergangenheit nicht aus dem Auge verlieren oder sich so weit in die Zukunft lehnen, dass man die Leute nicht mehr erreicht.

Ich lasse weiterhin jeden meiner Schüler mit C-Strings und selbstgeschriebenen Listen arbeiten, sowie Klassen dafür entwickeln und am Schluss Templates dafür entwickeln. Danach dürfen sie std::string oder std::vector verwenden. Auch strlen() ist verboten, bevor sie es nicht selbst geschrieben haben.
Der Weg programmieren zu lernen ist heute länger als vor 20 oder 30 Jahren, weil 20-30 Jahre Weiterentwicklung stattgefunden hat. Das Ziel 'Programmieren zu können' ist weiter weg. Aber um ans Ziel zu kommen gibt es keine Autobahn, keine Abkürzung und kein Wurmloch.
Abgesehen davon - die richtige Verwendung "alter" Techniken ist die Zukunft. Dafür sollte man nicht nur kennen, was zurzeit in Mode ist oder gehypt wird. Ansonsten wäre ich nämlich jetzt Ex-Delphi, Ex-Java, gegenwärtiger C#-Entwickler, statt seit bald 20 Jahren C++-Entwickler.

Alte Techniken sind in der Regel schneller als moderne - und fehleranfälliger, darum wurden sie verdrängt. Ich denke, dass man sich vieles nochmal genau anschauen sollte und statt alternativer Lösungen sich vielleicht Gedanken machen kann, ob die alten Techniken nicht semantisch abgesichert werden können.
Und da geht einiges. :-)

Auch wenn das durch Optimierung des Codes teils sicherlich obsolete ist, so wird eine Sprache damit eindeutig. Denn wenn jeder Konstruktor eine statische Variable hochzählt, dann stimmt entweder die statische Variable nicht bei allen Compilern oder die Optimierung wird dafür ausgeschaltet, obwohl der Entwickler gar kein zusätzliches, temporäres Objekt wünscht. Was der Entwickler wirklich will, muss er sagen können - unabhängig von der Optimizerstufe.
fat-lobyte hat geschrieben:
Xin hat geschrieben:Machst Du bei GDB/GIT weiter?
Ja, kann ich machen. Was ich nicht machen kann ist dir ein Versprechen abzugeben wann das geschieht. Leider.
Kein Problem, solange es so schnell wie möglich ist. :-)
Ich will proggen.org ja auch zum lernen nutzen. :-)

Re: [C++11] Uniform initialization - doch nicht so uniform?

Verfasst: Fr Mär 09, 2012 3:47 pm
von fat-lobyte
Xin hat geschrieben:Und bevor ich das jetzt kompiliere, weiß ich, dass das falsch ist, weil es das beliebte Beispiel ist, um das Chaos von Variablendeklarationen mit dem Standard-Konstruktor, bzw. verkorksten Funktionszeigerdefinitionen. :-)
Richtig. Warum dann die Frage?
Xin hat geschrieben:

Code: Alles auswählen

    A a=B();
oder bei explicit:
    A a = A(B());    
Wirklich nicht schön - aber nicht wirklich ein Problem.
Oder auch einfach A a{B{}}; oder A a{{}}; , wie im ersten Thread beschrieben.
Das Problem - die Funktionszeigerdeklarationen, die jeder ja jeden Tag benötigt, könnte man durch einen Kompatiblitätsmodus aus C herausoperieren. Macht man aber nicht.

Stattdessen bevorzugt man, dass man laufend diese Quizfrage gestellt bekommt.
Dieses Problem wurde mit den Braces als Initialisierung gelöst (siehe oben).
Die Syntax zur Definition von Funktionszeigern zu Ändern ist heute nicht mehr möglich, da zu viel (C *und* C++)-Code darauf beruht.
Mag sein, dass das in Genesys anders sein wird, bitte erkläre das aber an der richtigen Stelle.
Xin hat geschrieben:
fat-lobyte hat geschrieben:
Xin hat geschrieben:Du legst temporäre Objekte an, um sie zu kopieren.
Eben nicht! Das musste ich bisher, jetzt kann ich sie statt zu kopieren in das Objekt "hineinmoven".
Und das konntest Du vorher nicht?
Nein, RValues gabs damals noch nicht und man konnte außer per Zeiger keine Objekte "bewegen", nur kopieren.
Xin hat geschrieben:Hier wird es schwierig, denn was ein Compiler aus einer Initialisierungsliste macht ist nicht zwangsläufig das, was die Sprache semantisch hergibt. Sich darauf zu verlassen, dass der Compiler das Problem löst/wegoptimiert, obwohl die Sprache das semantisch gar nicht ausdrückt, kann zu interessanten Unterschieden zwischen Debug und Releaseversion führen.
Ich sehe hier keinen "Move".
Hier nicht, der Overhead fürs kopieren entspricht dem Kopieren von zwei Variablen. Wenn du noch nicht ganz verstanden hast, was Move-Konstruktoren sind, lies dir bitte diesen Thread durch: http://www.proggen.org/forum/viewtopic.php?f=21&t=4522
Dort ist auch ein Beispiel zu finden, wie so ein "Move" funktioniert.

fat-lobyte hat geschrieben:Aber hier gleich mal mein Hauptkriterium für eine gute Sprache:
Ich will ausdrücken können was ich denke. Die Konzepte will ich mit möglichst wenig Syntaktischem Overhead aufs papier bringen. Was ich nicht will ist es mit dem Compiler zu spielen, damit er tut was ich will oder mich in die Hardware einarbeiten wo ich für ein Paar Optimierungen den "Kopf brechen" muss - das soll verdammt noch mal der Compiler machen, dafür gibts ihn ja.
C++ mit seinen Templates ist (zumindest auf der Bibliotheks-Anwenderseite) verdammt gut darin. Kannst du das toppen?
Ja.
Dann bin ich mal gespannt. Seit C++11 sind meine Anforderungen an eine Sprache extrem hoch. Wenn du bereit bist, zeig mal was du hast.
Xin hat geschrieben:Du und ich benutzen Linux. Wenn jemand C oder C++ lernen möchte, dann ist sein primäres Ziel C und C++ zu lernen. Eventuell unter Windows.
Ich benutze aktuell den GCC 4.4. Meine Programme kompilieren auch mit VC2010.
Das ist klar, wenn man nicht die Möglichkeiten der Sprache ausreizt.
Xin hat geschrieben:In der Firma habe ich das Problem, dass einige Programmteile mit VC6 kompilieren müssen. Das ist schon leicht extrem, aber alte Compiler unterstützen zu müssen ist in Firmen ein recht übliches Problem.
Das ist Schade für dich, aber für mich wäre das inakzeptabel. In einem Privaten Projekt würde ich mir nie einfallen lassen VC 6 oder GCC < 4 zu unterstützen. Wenn ich dafür bezahlt werden würde, wäre das erste was ich machen würde meinen Chef dazu zu drängen, dass man die VC 6 Unterstützung aufgibt.

Xin hat geschrieben:Ich lasse weiterhin jeden meiner Schüler mit C-Strings und selbstgeschriebenen Listen arbeiten, sowie Klassen dafür entwickeln und am Schluss Templates dafür entwickeln. Danach dürfen sie std::string oder std::vector verwenden. Auch strlen() ist verboten, bevor sie es nicht selbst geschrieben haben.
Das ist eine Möglichkeit. Aber hast du dir überlegt, dass sie in der Zeit, in der sie sich mit strlen() abplagen auch andere Dinge höherer Abstraktion lernen könnten?
Nicht jeder der Programmieren lernt, wird später Programmierer. Es gibt genug Physiker, Biologen, Chemiker, und viele andere Wissenschaftler die Programmieren können müssen. Außerdem gibt es auch genug leute, die mit ihrem Computer einfach Dinge effizienter erledigen wollen, ansonsten sich aber nicht viel für Informatik interessieren.
Solchen leuten würde ich vieles nicht zumuten wollen, und ihnen aber auch nicht das Programmieren verwehren. Nicht in C, aber gerade in C++ kann man einige Aufgaben mit höher abstrahierten Methoden erledigen.

Der Weg programmieren zu lernen ist heute länger als vor 20 oder 30 Jahren, weil 20-30 Jahre Weiterentwicklung stattgefunden hat. Das Ziel 'Programmieren zu können' ist weiter weg. Aber um ans Ziel zu kommen gibt es keine Autobahn, keine Abkürzung und kein Wurmloch.
Das ist Blödsinn. Die 20-30 Jahre Entwicklung, die stattgefunden haben müssen nicht von jedem Schüler erneut durchgemacht werden. Leider wird das aber oft so unterrichtet, weil die Lehrenden diesen Weg eben selbst miterlebt haben.
Das Wurmloch und die Abkürzung nennt man dann "Reflexion" - nachdenken darüber was sinnvoll ist und was nicht.
Abgesehen davon - die richtige Verwendung "alter" Techniken ist die Zukunft. Dafür sollte man nicht nur kennen, was zurzeit in Mode ist oder gehypt wird. Ansonsten wäre ich nämlich jetzt Ex-Delphi, Ex-Java, gegenwärtiger C#-Entwickler, statt seit bald 20 Jahren C++-Entwickler.
Natürlich braucht man auch low-level Menschen, das ist gar keine Frage. Die Frage ist: wie viele braucht man? Soll man jeden Programmierer dazu ausbilden zuerst seine eigene strlen() funktion zu Programmieren? Wie viele implementierungen gibt es, würdest du schätzen? Ich bin mittlerweile etwas lockerer mit C#/Java, da ich akzeptiert habe dass es auch in Ordnung ist, auch vorgefertigte Frameworks zu verwenden um (schnell!) sein Ziel zu erreichen.

Wer nur einen Hammer hat, sieht überall nur Nägel. C++ ist mein Hammer - das ist auch keine gute Sache. Deswegen habe ich Java versucht und Python gelernt (aber auch x86-Assembler).
Alte Techniken sind in der Regel schneller als moderne
Das kann man so nicht stehenlassen. Wenn man Abstraktionsschichten dazwischenschiebt, dann vielleicht (aber nicht zwangsläufig).
Wenn das Problem aber richtig angegangen wird, sind manche "moderne" Techniken sogar schneller. Vergleiche std::sort<>() mit qsort(). Kleine herausforderung: schreibe eine schnellere und gleich generische Klasse als std::vector<>. Dann lassen wir sie im Test gegen die Implementierung von Visual Studio oder libstdc++ antreten.
Ich denke, dass man sich vieles nochmal genau anschauen sollte und statt alternativer Lösungen sich vielleicht Gedanken machen kann, ob die alten Techniken nicht semantisch abgesichert werden können.
Und da geht einiges. :-)
Da ist vl. was dran.
Auch wenn das durch Optimierung des Codes teils sicherlich obsolete ist, so wird eine Sprache damit eindeutig. Denn wenn jeder Konstruktor eine statische Variable hochzählt, dann stimmt entweder die statische Variable nicht bei allen Compilern oder die Optimierung wird dafür ausgeschaltet, obwohl der Entwickler gar kein zusätzliches, temporäres Objekt wünscht. Was der Entwickler wirklich will, muss er sagen können - unabhängig von der Optimizerstufe.
Das ist ein konstruirtes Problem. Was ich will ist, dass mein Objekt initialiert ist. Was ich will ist, dass mein Computer das erledigt was ich will, in absehbarer Zeit. Dafür gibt es C überhaupt - eine Abstraktion weg von assembler. Mir ist egal wie und was da passiert, solange a) das Ergebnis das gleiche und b) die Laufzeit kurz ist. Für a) gibt es Standardisierungen, für b) gibt Compiler mit guten Optimizern. Klar hilft es, wenn man eine ungefähre Ahnung von den Laufzeiten seiner algorithmen hat (O(n), O(ln n), O(n^2), oder wie sie heißen...) Aber es heißt NICHT dass man seinen Code auf eine CPU schreibt und sich dann wundert, warums auf anderen Systemen auf einmal langsmer läuft.

[quote="Xin]
fat-lobyte hat geschrieben:
Xin hat geschrieben:Machst Du bei GDB/GIT weiter?
Ja, kann ich machen. Was ich nicht machen kann ist dir ein Versprechen abzugeben wann das geschieht. Leider.
Kein Problem, solange es so schnell wie möglich ist. :-)
Ich will proggen.org ja auch zum lernen nutzen. :-)[/quote]
Versteh ich. Aber ich sollte auch mal langsam an Prüfungen und meine Bachelorarbeit denken.