Guten Abend,
sehr vereinfacht gesagt habe ich eine Funktion welches aus einer Zahl
einen String macht.
Aktuell habe ich dafür vier Funktionen:
void funct1( uint8_t z, char* Buffer)
void funct2( uint16_t z, char* Buffer)
void funct3( int8_t z, char* Buffer)
void funct4( int16_t z, char* Buffer)
Eigentlich machen die Funktionen fast alle das Gleiche - daher habe ich
gedacht, dass es doch eine Möglichkeit geben müsste, den Typ einer
Variablen zu "testen" und der Funktion einen "undefinierten
Variablentyp" zu übergeben.
Geht sowas ?
void funct1( undefined z, char* Buffer)
Wenn ja - wie genau?
Danke!
Tom schrieb:> Sprache C,
Dann nein.
Tom schrieb:> Compiler GCC (AVR Studio)
C++ möglich
Tom schrieb:> Ziel: Möglichst sparsam mit Ressourcen
Da tun sich C und C++ nichts.
Wie wärs wenn du eine Funktion baust die alle Fälle abdeckt wobei
zusätzlich der Typ mit den Parametern übergeben wird und dann die 4
Funktionen diese allgemeine Funktion aufrufen lässt? Je nach Parameter
wird dann eben mit 00 aufgefüllt bzw. das Vorzeichen ausgewertet
zitter_ned_aso schrieb:
[Generics]
gaudiamus schrieb:> Wie wärs wenn du eine Funktion baust die alle Fälle abdeckt wobei> zusätzlich der Typ mit den Parametern übergeben wird
...
Unübersichtlich. Im zweiten Fall auch unsinnig (wenn er bei jedem
Funktionsaufruf im Code selber auf den Typ des Parameters schauen muß,
kann er auch gleich jeweils die richtige Funktion wählen).
Genau dafür hat C++ die Funktionsüberladung bekommen. Einfach alle 4
Funktionen gleich nennen und dann sucht sich der Compiler bei jedem
Aufruf jeweils die raus, die zu den verwendeten Argumenten paßt. Wenn er
den AVR-GCC benutzt, dann hat er C++ zur Hand. Am Ende ist das auch
nichts anderes als die Lösung mit Generics. Wahrscheinlich sieht sogar
der Objectcode jeweils gleich aus. Nur die Symbole für die
Funktions-Einsprünge werden mit C++ anders aussehen
(https://en.wikipedia.org/wiki/Name_mangling)
Und wenn der TE das wegen einer C++ Phobie nicht mag, dann soll er es
halt lassen. keine Arme, keine Kekse!
Peter D. schrieb:> Tom schrieb:>> Ziel: Möglichst sparsam mit Ressourcen>> Ziel verfehlt.> Das Überladen mit C++ erzeugt trotzdem alle 4 verschiedenen Funktionen
Ja. Genauso wie die C-Variante mit 4 Einzelfunktionen. Unabhängig davon,
ob man noch Generics drüberstülpt oder nicht.
> Will man optimieren
Der Ruf nach Optimierung erscheint mir hier fehl am Platze. Was will man
denn da optimieren? Entweder eine dieser Funktionen wird gebraucht
(vulgo: aufgerufen), dann muß sie der Compiler auch generieren. Oder sie
wird nicht gebraucht, dann kann er sie weglassen. Und mit den richtigen
Optionen für Compiler und Linker machen gcc und GNU ld das auch.
Wenn es darum geht, möglichst kompakten Binärcode zu erzeugen, dann
würde man damit anfangen, gar nicht erst zig Funktionen zu schreiben,
die am Ende alle nur das gleiche machen.
Andererseits ist das vermutlich auch wieder ein Fall von verfrühter
Optimierung. Der TE zeigt zwar keine Implementierung, aber es soll ja
wohl eine Art sprintf() werden. Da machen seine "Funktionen"
wahrscheinlich kaum mehr, als itoa() und utoa() aufzurufen. Der
eigentliche Funktionsrumpf dürfte minimal sein, was diese Funktionen zu
idealen Kandidaten für inlining macht.
Warum das Rad neu erfinden? "sprintf" tut's doch. Und wenn's um eine
"Minimalversion" geht, schreibt man sich halt eine abgespeckte Version,
aber weiterhin mit varargs wie beschrieben:
https://en.wikipedia.org/wiki/Variadic_function#In_C
Nachteil ist, dass man die Information, um welchen Datentyp es geht,
explizit der Funktion mitgeben muss. Und der Compiler prüft halt nicht,
ob der Datentyp stimmt, ggf. gibt's also Chaos ...
A. B. schrieb:> Nachteil ist, dass man die Information, um welchen Datentyp es geht,> explizit der Funktion mitgeben muss. Und der Compiler prüft halt nicht,> ob der Datentyp stimmt, ggf. gibt's also Chaos ...
Es gibt beim gcc das attribute __attribute__((format(printf,1,2))).
Wobei hier 1 der Index des String Formates ist (Index beginnt bei 1) und
2 der Index des ersten Arguments, das überprüft werden soll.
https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html
Klimatester schrieb:> Kommt drauf an welche Sprache und Compiler.
Da hat Klimatester recht.
Mit Objectpascal (Delphi) ginge so etwas. Objectpascal kennt den Typ
Variant, der alle Datentypen abbilden kann. Dort gibt es auch Funktionen
mit denen man ermitteln kann von welchem Typ die Daten sind.
Wo Licht ist ist natürlich auch Schatten:
-variante Typen brauchen mehr Speicher
-die Verarbeitung variander Typen ist langsamer
Ich habe Varianten für den umgekehrten Weg eingesetzt um aus beliebigen
numerischen Strings Zahlen zu machen. Die Funktion liefert ein Ergebnis
vom Typ Variant, das man allen Zahlentypen in Delphi zu weisen kann.
In C scheint das nicht so einfach zu sein. Das was hie an Code gezeigt
wurde erzeugt letztendlich auch 4 Funktionen.
Arduino Fanboy D. schrieb:> Damit möglich:> -Funktionen überladen
Auch das Überladen sind am Ende mehrere Funktionen, allerdings mit dem
Vorteil das alle Funktionen den gleichen Namen besitzen und an Hand des
Datentyps entschieden wird welche Funktion letztendlich aufgerufen wird.
nfet schrieb:> void func(void* zahl, int typ, char* buffer)
Einzige Möglichkeit in C scheint zu sein, indem ich der Funktion
mitteile welchen Datentyp ich übergebe.
Zeno schrieb:> Mit Objectpascal (Delphi) ginge so etwas. Objectpascal kennt den Typ> Variant, der alle Datentypen abbilden kann. Dort gibt es auch Funktionen> mit denen man ermitteln kann von welchem Typ die Daten sind.
Genau das geht in C++ auch, C++ hat ebenfalls einen Typ variant.
Zeno schrieb:> Einzige Möglichkeit in C scheint zu sein, indem ich der Funktion> mitteile welchen Datentyp ich übergebe.
Das ist aber sogar weniger effizient als Überladungen in C++, weil
dadurch zusätzlich die Laufzeit-Unterscheidung hinzu kommt.
Axel S. schrieb:> Am Ende ist das auch> nichts anderes als die Lösung mit Generics. Wahrscheinlich sieht sogar> der Objectcode jeweils gleich aus.
Genau so ist es. Nur dass Funktionsüberladungen in C++ doch deutlich
einfacher & übersichtlicher sind.
Alex D. schrieb:> Es gibt beim gcc das attribute __attribute__((format(printf,1,2))).> Wobei hier 1 der Index des String Formates ist (Index beginnt bei 1) und> 2 der Index des ersten Arguments, das überprüft werden soll.> https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html
Jaaaa, aber nur wenn man sich an die "printf"-Konventionen für den
Format-String hält. Dann ist man aber schon fast wieder beim normalen
"sprintf". Wenn man nur eine abgespeckte Version oder gänzlich andere
implementiert, hilft das wenig.
Man kann freilich den gcc auch eine selbstgestrickte Konvention
beibringen ...
Ich würde zu C++ mit templates raten. Was die Codegröße betrifft, macht
das zwar keinen Unterschied zu überladenen Funktionen - es werden immer
noch Funktionen für alle Typen generiert, die man nutzt, aber man muss
wenigstens nicht n separate Implementationen der selben Funktion
schreiben, die sich nur im übergebenen Typ und der Anzahl der
auszuwertenden Bits unterscheiden.
A. B. schrieb:> Jaaaa, aber nur wenn man sich an die "printf"-Konventionen für den> Format-String hält. Dann ist man aber schon fast wieder beim normalen> "sprintf". Wenn man nur eine abgespeckte Version oder gänzlich andere> implementiert, hilft das wenig.
Wenn man den Format-String komplett anders aufbaut, magst du recht
haben.
Aber solange man ein Subset mit gleicher Syntax wie bei printf
verwendet, klappt das natürlich schon. Wenn der übergebene Typ nicht zum
Format-Specifier passt, gibt es immer noch eine Warnung.
Rolf M. schrieb:> aber man muss> wenigstens nicht n separate Implementationen der selben Funktion> schreiben, die sich nur im übergebenen Typ und der Anzahl der> auszuwertenden Bits unterscheiden.
Wenn das denn so ist. Wenn die Funktionen sonst komplett unterschiedlich
sind, bringen templates hier gar nichts. Wenn die Funktionen sich derart
ähnlich sind, sind templates sinnvoll, und produzieren auch nicht mehr
Code als einzeln manuell implementierte Funktionen.
Programmierer schrieb:> Rolf M. schrieb:>> aber man muss wenigstens nicht n separate Implementationen der selben>> Funktion schreiben, die sich nur im übergebenen Typ und der Anzahl der>> auszuwertenden Bits unterscheiden.>> Wenn das denn so ist. Wenn die Funktionen sonst komplett unterschiedlich> sind, bringen templates hier gar nichts.
Nun, das Ursprungsposting klang für mich nicht danach, dass diese
Funktionen alle vollkommen unterschiedlich implementiert sind bzw. sein
müssten.
Zeno schrieb:> Einzige Möglichkeit in C scheint zu sein, indem ich der Funktion> mitteile welchen Datentyp ich übergebe.
Hast Du _Generics oben gelesen und verstanden? Das ist im Endeffekt
genauso wie eine überladene Funktion in C++.
Das geht deswegen nicht in C/C++ weil ein Zeiger auf unbekannte Daten
nichts anderes ist, als die Adresse eines Speicherbereiches im RAM.
Weder der Zeiger noch die Daten enthalten irgendwelche Informationen
über die Art und Größe der Daten - es sei denn, du legst diese
Informationen mit in den Daten ab. Dann machst du im Grunde genommen das
zu Fuß, was C++ mit std::variant macht.
Wenn du aber std::variant bzw. deine selbst gebastelte Datenstruktur mit
Typ-Informationen verwendest, dann bist du auch dazu gezwungen. Die
Funktion lässt sich dann nicht mit andere Datenstrukturen verwenden. Sie
zwingt dich dazu, alles in einen variant zu verpacken.
Stefan ⛄ F. schrieb:> Weder der Zeiger noch die Daten enthalten irgendwelche Informationen> über die Art und Größe der Daten
Der Typ der Variablen, welcher dem Compiler bekannt ist enthält diese
Information. Daher kann der Compiler den Aufruf an den richtigen
Overload oder die richtige Generic-Function erzeugen. Diese Auflösung
geschieht aber während des Kompilierens, und zur Laufzeit ist diese
Information nicht verfügbar ("Type Erasure"). C und C++ besonders sind
stark typisierte Sprachen, d.h. der Compiler hat diese Information eben
doch.
Rolf M. schrieb:> Ich würde zu C++ mit templates raten.
Ich nicht. ich sehe nämlich bei dieser Anwendung gar keinen Vorteil von
Templates.
> Was die Codegröße betrifft, macht> das zwar keinen Unterschied zu überladenen Funktionen - es werden immer> noch Funktionen für alle Typen generiert, die man nutzt, aber man muss> wenigstens nicht n separate Implementationen der selben Funktion> schreiben
Jein. Man kann mit Templates natürlich eine generische Implementierung
schreiben. Aber nur dann, wenn es eine solche generische Implementierung
auch gibt. Wie sollte die denn aber aussehen? Das ist ja gerade der
Witz, daß man für verschieden lange Integer beiderlei signedness auch
jeweils verschiedene _X_toa Funktionen aus der stdlib aufrufen muß. Mit
anderen Worten: man muß separate Implementierungen für diese Typen
explizit hinschreiben.
Schon schwindet jeglicher Vorteil gegenüber normaler
Funktionsüberladung. Aber man hat den syntaktischen Overhead von
Templates.
Wenn man eine C++ Lösung haben will, würde man eher das Streams
Interface benutzen. Und ganz besonders würde man nicht mit char* Buffern
herumhantieren. C-Strings und nackte Pointer haben in einem C++ Programm
nichts zu suchen. Außer vielleicht da, wo man mit legacy C-Code
interoperieren muß.
Programmierer schrieb:> Der Typ der Variablen, welcher dem Compiler bekannt ist enthält diese> Information. Daher kann der Compiler den Aufruf an den richtigen> Overload oder die richtige Generic-Function erzeugen
Ja schon, aber nur bei C++.
Der TO wollte aber nicht viele Varianten der Funktion, zwischen denen
der Compiler wählt, sondern eine Funktion die sich selbst darum kümmert
- zur Laufzeit.
Axel S. schrieb:> Das ist ja gerade der> Witz, daß man für verschieden lange Integer beiderlei signedness auch> jeweils verschiedene _X_toa Funktionen aus der stdlib aufrufen muß.
Es sei denn, man schreibt eine generische X_toa-Funktion welche das
automatisch für alle Breiten korrekt macht. Das ist recht einfach.
Axel S. schrieb:> Wenn man eine C++ Lösung haben will, würde man eher das Streams> Interface benutzen.
Die sind leider nicht sehr Mikrocontroller-Geeignet. Selbst Arduino
nutzt Overloads:
https://www.arduino.cc/reference/de/language/functions/communication/serial/print/Stefan ⛄ F. schrieb:> Ja schon, aber nur bei C++.
Nein, auch bei C. Sonst könnte der Compiler keine Fehlermeldung ausgeben
bei Dingen wie "puts(42);", wenn er nicht wüsste, dass "42" vom Typ
"int" ist, aber "puts" ein "const char*" Argument braucht. Außerdem
braucht er das für _Generic.
Stefan ⛄ F. schrieb:> Der TO wollte aber nicht viele Varianten der Funktion, zwischen denen> der Compiler wählt, sondern eine Funktion die sich selbst darum kümmert> - zur Laufzeit.
Ganz sicher?
Axel S. schrieb:> Wenn man eine C++ Lösung haben will, würde man eher das Streams> Interface benutzen. Und ganz besonders würde man nicht mit char* Buffern> herumhantieren. C-Strings und nackte Pointer haben in einem C++ Programm> nichts zu suchen. Außer vielleicht da, wo man mit legacy C-Code> interoperieren muß.
Wir sprechen hier von einer ressourcensparenden Implementation auf
AVR-µCs.
Stefan ⛄ F. schrieb:> Der TO wollte aber nicht viele Varianten der Funktion, zwischen denen> der Compiler wählt, sondern eine Funktion die sich selbst darum kümmert> - zur Laufzeit.
Ich hab das nicht so verstanden, dass er das unbedingt zur Laufzeit tun
will, sondern eben, dass er sich das Schreiben von mehreren fast genau
gleichen Funktionen ersparen möchte.
Programmierer schrieb:>> Der TO wollte aber nicht viele Varianten der Funktion, zwischen denen>> der Compiler wählt, sondern eine Funktion die sich selbst darum kümmert>> - zur Laufzeit.> Ganz sicher?
So habe ich ihn jedenfalls verstanden. Warum auch immer, besonders
Sinnvoll kommt es mir nicht vor.
Rolf M. schrieb:> Ich hab das nicht so verstanden, dass er das unbedingt zur Laufzeit tun> will, sondern eben, dass er sich das Schreiben von mehreren fast genau> gleichen Funktionen ersparen möchte.
Das können einem _Generic und auch C++ Überladungen nicht ersparen.
Macht die Sache nur einfacher, für den Nutzer.
Per Template Funktion, bekommt man das alles in einen Funktionsrumpf
gestopft. Wird hässlich.
Aber am Ende des Tages werden die spezialisierten Funktionen dann doch
vom Compiler automatisch generiert.
Nix mit Speichereinsparung.
Denn es muss getan werden, was getan werden muss.
Stefan ⛄ F. schrieb:> Der TO wollte aber nicht viele Varianten der Funktion, zwischen denen> der Compiler wählt, sondern eine Funktion die sich selbst darum kümmert> - zur Laufzeit.
Zur Laufzeit macht wenig Sinn. Weshalb sollte das der TO gemeint haben.
Eine typische Anwendung ist eine Diagnose-Funktionalität. Ich möchte
Variablen listen, über die ein Code automatisch traversiert. Und je nach
Typ soll der Compiler deren Wert sinnvoll darstellen, ohne dass ich das
angeben muss (oder überhaupt schon weiß, vielleicht ändert es sich ja)
Für die Größe reicht sizeof, geschenkt.
aber ob ich -1 oder 255 anzeigen soll, ist schon wichtiger. Wenn ich die
Variablen MyIndex, MyCount und MyWhatever habe, möchte ich vielleicht
einfach
Add(MyCount), Add(MyIndex), Add(MyWhatever) hinschreiben.
Ein paralleles Pflegen des Types (wie z.B. bei printf) ist eine üble
Sache. (wobei printf und Co ja noch übler werden, wenn int mal 2 und mal
4 Byte groß sein kann. Ja, geht, herhackt die Strings aber noch weiter)
Programmierer schrieb:> Wenn die Funktionen sonst komplett unterschiedlich> sind, bringen templates hier gar nichts. Wenn die Funktionen sich derart> ähnlich sind, sind templates sinnvoll, und produzieren auch nicht mehr> Code als einzeln manuell implementierte Funktionen.
Unsinn.
Jede Verwendung für eine beliebige Kombination konkreter Typen erzeugt
natürlich zwangsweise Code für eben diese Typkombination. D.h.: dieser
abstrakte Quatsch ist nur dann ohne Impact auf die Codegröße, solange er
nicht tatsächlich konkret benutzt wird.
Sprich: dein Code auf Quelltextebene wird durch Sachen wie Templates und
überladene Funktionen übersichtlicher, weil kürzer. Das ist schon alles,
was diese Syntax-Gimmicks bringen...
Da, wo tatsächlich geackert wird, auf der Ebene der Hardware, bringt das
garnix. Es ist eher so, dass durch diese beschwingte Leichtigkeit auf
der abgehobenen Ebene des Hochsprachencodes die Tendenz steigt, Code,
den man tatsächlich vereinheitlichen könnte, nicht wirklich zu
vereinheitlichen, sondern immer und immer wieder zu PHYSISCH zu
manifestieren. Das schadet der Performance direkt immerhin so gut wie
garnicht, ist aber bezüglich der Codegröße und damit bei vielen
Architekturen indirekt (durch die begrenzte Größe von Caches) doch auch
wieder bezüglich der Performance ziemlich teuer.
Die Auswirkungen dieser krassen Fehlentwicklung kann man sich an
praktisch jeder üblichen PC-Anwendung ansehen, wenn man sie über die
Jahre mit konstanter Hardwarepower beobachtet...
c-hater schrieb:> Jede Verwendung für eine beliebige Kombination konkreter Typen erzeugt> natürlich zwangsweise Code für eben diese Typkombination.
Genau den Code, den man bei manueller Implementation auch erzeugt hätte.
Nullsummenspiel.
c-hater schrieb:> Das ist schon alles, was diese Syntax-Gimmicks bringen...
Das ist aber eine Menge. Vermeidung von Wiederholung hilft gegen Fehler
und unwartbaren Code.
c-hater schrieb:> Da, wo tatsächlich geackert wird, auf der Ebene der Hardware, bringt das> garnix.
Das ist nicht die einzige Ebene, die zählt. Git bringt auf der Hardware
Ebene auch nix. Verwenden sollte man es trotzdem.
c-hater schrieb:> Es ist eher so, dass durch diese beschwingte Leichtigkeit auf der> abgehobenen Ebene des Hochsprachencodes die Tendenz steigt, Code, den> man tatsächlich vereinheitlichen könnte, nicht wirklich zu> vereinheitlichen, sondern immer und immer wieder zu PHYSISCH zu> manifestieren.
Hast du dafür auch nur den Hauch eines Beweises? Diese Argumentation ist
so wie zu sagen "wenn der Handwerker eine Bohrmaschine zur Verfügung
hat, tendiert er dazu diese für alles zu benutzen. Daher sollte man
Bohrmaschine gar nicht verwenden."
Außerdem werden duplizierte templates sowieso wegoptimiert.
c-hater schrieb:> Die Auswirkungen dieser krassen Fehlentwicklung kann man sich an> praktisch jeder üblichen PC-Anwendung ansehen, wenn man sie über die> Jahre mit konstanter Hardwarepower beobachtet...
Die sind sowieso kaum noch in C++ geschrieben, und wenn dann sind
templates nicht an Performance Problemen schuld. Die Haupt Bremse in den
meisten Fällen sind schlecht konstruierte Datenstrukturen und
Algorithmen. Die Sprache ist da eher drittrangig.
Arduino Fanboy D. schrieb:> Rolf M. schrieb:>> Ich hab das nicht so verstanden, dass er das unbedingt zur Laufzeit tun>> will, sondern eben, dass er sich das Schreiben von mehreren fast genau>> gleichen Funktionen ersparen möchte.>> Das können einem _Generic und auch C++ Überladungen nicht ersparen.
Deshalb habe ich ja auch nicht die, sondern Templates empfohlen.
> Per Template Funktion, bekommt man das alles in einen Funktionsrumpf> gestopft. Wird hässlich.
Glaube ich nicht.
> Aber am Ende des Tages werden die spezialisierten Funktionen dann doch> vom Compiler automatisch generiert.
Das habe ich auch schon geschrieben.
c-hater schrieb:> Jede Verwendung für eine beliebige Kombination konkreter Typen erzeugt> natürlich zwangsweise Code für eben diese Typkombination.
Soweit waren wir schon.
> Sprich: dein Code auf Quelltextebene wird durch Sachen wie Templates und> überladene Funktionen übersichtlicher, weil kürzer. Das ist schon alles,> was diese Syntax-Gimmicks bringen...
Ich finde, dass kompakter und übersichtlicher Quellcode durchaus ein
erstrebenswertes Ziel ist.
> Da, wo tatsächlich geackert wird, auf der Ebene der Hardware, bringt das> garnix. Es ist eher so, dass durch diese beschwingte Leichtigkeit auf> der abgehobenen Ebene des Hochsprachencodes die Tendenz steigt, Code,> den man tatsächlich vereinheitlichen könnte, nicht wirklich zu> vereinheitlichen, sondern immer und immer wieder zu PHYSISCH zu> manifestieren.
Das gilt nur, wenn man nicht weiß, was man tut. Es ist eben wie mit
jedem Werkzeug: Wenn man nicht damit umgehen kann, wird man damit auch
keine guten Ergebnisse erzielen.
Rolf M. schrieb:> Das gilt nur, wenn man nicht weiß, was man tut. Es ist eben wie mit> jedem Werkzeug: Wenn man nicht damit umgehen kann, wird man damit auch> keine guten Ergebnisse erzielen.
Tja, womit wir zum Kern des Problems kommen: Ganz offensichtlich können
die meisten C++-Programmierer mit ihrem Werkzeug halt nicht umgehen und
erzielen deshalb nur eher bescheidene Ergebnisse...
Wie schon gesagt: jede größere Anwendung für den PC enthält unzählige
Beispiele dafür. Und es werden mit jeder Version derselben Software
mehr. Das ist inzwischen so signifikant, dass man nicht mal mehr den
Code analysieren muss, es reichen Mustererkennung und statistische
Methoden zur Auswertung. Mal ganz abgesehen von dem Sachverhalt, dass es
fühlbar und messbar immer langsamer wird, dieselben Sachen zu tun, die
man auch früher mit dem Vorläufer derselben Software getan hat...
Ich behaupte: Es liegt daran, weil sie (also die Programmierer) nie
gelernt haben, zu verstehen, was da zur Laufzeit wirklich passiert, wenn
sie diesen Kram benutzen. Nicht zuletzt etliche Beiträge in diesem
Thread hier beweisen das wirklich eindringlichst...
c-hater schrieb:> Wie schon gesagt: jede größere Anwendung für den PC enthält unzählige> Beispiele dafür.
Dann zeig mir doch mal eine PC-Anwendung und 3 dieser unzähligen
Beispiele, wo templates die Performance gegenüber einer templatelosen
Alternative signifikant beeinträchtigen.
c-hater schrieb:> Ich behaupte: Es liegt daran, weil sie (also die Programmierer) nie> gelernt haben, zu verstehen, was da zur Laufzeit wirklich passiert, wenn> sie diesen Kram benutzen.
Nicht jeder Programmierer der Welt hat den Luxus, das alles ausführlich
zu lernen. So viele Hochschulen gibt es gar nicht. Und so viel sind die
Kunden gar nicht bereit für durch hochqualifiziertes Personal erstellte
Software zu zahlen - ob Cash, Werbung oder Nutzerdaten.
c-hater schrieb:> Tja, womit wir zum Kern des Problems kommen: Ganz offensichtlich können> die meisten C++-Programmierer mit ihrem Werkzeug halt nicht umgehen und> erzielen deshalb nur eher bescheidene Ergebnisse...
Du wieder mit deinen Verallgemeinerungen.
Wenn die meisten C++ Programmierer unfähig wären, würde man heute nicht
immer noch so viel in C++ schreiben. Denn die Entscheider hätten
aufgrund der schlechten Ergebnisse auf etwas anderes gewechselt.
Stefan ⛄ F. schrieb:> c-hater schrieb:>> Tja, womit wir zum Kern des Problems kommen: Ganz offensichtlich können>> die meisten C++-Programmierer mit ihrem Werkzeug halt nicht umgehen und>> erzielen deshalb nur eher bescheidene Ergebnisse...>> Du wieder mit deinen Verallgemeinerungen.>> Wenn die meisten C++ Programmierer unfähig wären, würde man heute nicht> immer noch so viel in C++ schreiben. Denn die Entscheider hätten> aufgrund der schlechten Ergebnisse auf etwas anderes gewechselt.
Das Problem ist, das er gar nicht gemerkt hat, daß seine Argumentation
das genau konträre Ergebnis belegt. Nur eben nicht, wenn man jedes
Argument als Beleg für die eigene "Wahrheit" sieht.
Carl D. schrieb:> er gar nicht gemerkt
Für mich ist die Sache klar!
Behauptungen, ohne Belege.
So tun, als wäre es Wahrheit.
Ist Lüge.
Niederträchtige Lüge und Diffamierung.
Fachlich blitzt ja bei unserem C-Hasser manchmal was auf.
Aber ansonsten, sein Sozialverhalten, ist hier unter aller Sau.