C++11: user defined literals

Vom einfachen Programm zum fertigen Debian-Paket, Fragen rund um Programmiersprachen, Scripting und Lizenzierung.
Benutzeravatar
schorsch_76
Beiträge: 2535
Registriert: 06.11.2007 16:00:42
Lizenz eigener Beiträge: MIT Lizenz

C++11: user defined literals

Beitrag von schorsch_76 » 19.06.2014 11:21:52

Aus den Talk von Bjarne Stroustroup [1] habe ich hier ein kleines kompilierbares File gemacht. Es zeigt die Verwendung von user defined literals anhand der physikalischen Einheiten Distanz/Zeit/Geschwindigkeit. Ich finde das schon sehr cool. Damit gibt es keine Einheitenfehler mehr. Es ist immer klar in welcher Einheit ein Wert ist. Generel finde ich diesen Talk Klasse und er zeigt einem viele bessere Wege wie man mit C++11 viele schöne Sachen machen kann.

Mit diesen user defined literals passiert alles zur Compiletime, es braucht nicht mehr Zyklen und mehr Speicher auf dem Target, kann damit auf auf embedded Systemen genutzt werden.

Das geht sicher nicht mit plain C 8O

Code: Alles auswählen

template<int M, int K, int S> 
struct Unit { // a unit in the MKS system
	enum {m=M, kg=K, s=S };
};

template <typename Unit> // a magnitude with a unit
struct Value {
	double val;	// the magnitude
	constexpr Value(double d) : val(d) {}
};

// Time
using sec = Unit<0,0,1>;		// the base unit
using min = Unit<0,0,60>;		// minitues
using hour = Unit<0,0,3600>;		// hour
using time = Value<sec>;		// time: base unit seconds
constexpr time operator"" s(long double d)
{
        return time(d);
}
constexpr time operator"" min(long double d)
{
	return time(d * min::s);
}
constexpr time operator"" h(long double d)
{
	return time(d * hour::s);
}

// Time square
using sec2 = Unit<0,0,2>;		// base unit
using time2 = Value<sec2>;		// the physical value
constexpr time2 operator"" s2(long double d)
{
	return time2(d);
}

// distance
using m = Unit<1,0,0>;			// base unit
using km = Unit<1000,0,0>;		// kilometers
using distance = Value<m>;		// the physical value
constexpr distance operator"" m(long double d)
{
	return distance(d);
}
constexpr distance operator"" km(long double d)
{
	return distance(d * km::m);
}

// acceleration
using m_s2 = Unit<1,0,-2>;		// base unit meters/second/second
using accel = Value<m_s2>;		// the physical value
constexpr accel operator"" m_s2 (long double d)
{
	return accel(d);
}

// speed
using m_s = Unit<1,0,1>;		// the base unit
using speed = Value<m_s>;		// the physical value

using km_h = Unit<1000,0,3600>;		// km/h
constexpr speed operator"" m_s(long double d)
{
	return speed(d);
}

constexpr speed operator/(distance d, time t)
{
	return speed(d.val/t.val);
}
int main(int argc, char** argv)
{
	time t = 1.0s;
	speed s1 = 100.0m / 9.8s; // very fast for a human

	speed s2 = 1.2km / 0.5h; // slow going
	speed s3 = 1.2km / 30.0min; // the same speed

	// speed s2 = 100 / 9.8s; // error
}

[1] http://www.youtube.com/watch?v=0iWb_qi2-uI

Benutzeravatar
peschmae
Beiträge: 4844
Registriert: 07.01.2003 12:50:33
Lizenz eigener Beiträge: MIT Lizenz
Wohnort: nirgendwo im irgendwo

Re: C++11: user defined literals

Beitrag von peschmae » 19.06.2014 12:13:20

Einerseits ja sehr cool, was da mittlerweile alles tolles geht.

Andererseits wie bei vielen C++-Abstraktionen erst auch mal für den unbedarften Leser erstmal sehr undurchschaubar. Und bei C++ ist es ja leider schon so, dass man die Sachen spätestens nach dem ersten Speicherzugriffsfehler dann doch durchblicken muss, um dem ganzen Herr zu werden...

Das muss halt erst mal einer alles in eine schöne Bibliothek packen, und dann muss man sich einarbeiten. Dann wird das aber schon richtig toll. Und ja, C++11 ist ganz allgemein super!

MfG Peschmä
"er hätte nicht in die usa ziehen dürfen - die versauen alles" -- Snoopy

ctwx
Beiträge: 321
Registriert: 04.04.2010 23:06:55
Lizenz eigener Beiträge: MIT Lizenz

Re: C++11: user defined literals

Beitrag von ctwx » 19.06.2014 13:57:46

Ich habe mir deinen ganzen Code noch nicht angeschaut, aber dein struct-enum-Konstrukt kannst du meine ich auch als "class enum" schreiben, oder sehe ich das falsch? http://www.cprogramming.com/c++11/c++11 ... class.html

*mal den Code weiterlesen & verstehen :D*
Nachtrag:
Ich habe mir die user defined literals mal weiter angeschaut. Sehr tolles Feature, kannte ich noch nicht und dein Beispiel finde ich auch sehr gut. Danke!

Benutzeravatar
schorsch_76
Beiträge: 2535
Registriert: 06.11.2007 16:00:42
Lizenz eigener Beiträge: MIT Lizenz

Re: C++11: user defined literals

Beitrag von schorsch_76 » 19.06.2014 19:12:23

Das was ich da geschrieben habe ist fast 1zu1 aus dem Youtube Video. km, h, min habe ich reingemacht wie den operator / (distance, time). B.S. zeigt das genau so ein Fehler (Einheitenfehler) zum Verlust eines Marsvehikels im Wert von ca 560 Mio $ geführt hat. Das ganze schön in einen namespace rein und gut :) . Afaik gibt es auch Boost::Units was in diese Richtung geht.

Benutzeravatar
bmario
Beiträge: 1256
Registriert: 05.09.2007 12:15:47
Lizenz eigener Beiträge: MIT Lizenz
Wohnort: Dresden

Re: C++11: user defined literals

Beitrag von bmario » 26.06.2014 01:16:11

Das Schlimme ist, dass das Beispiel nicht standard-konform ist.
§17.6.4.3.5 hat geschrieben:Literal suffix identifiers that do not start with an underscore are reserved for future standardization.
Nichts zu tun ist viel besser,
als mit viel Mühe nichts zu schaffen. - Laotse

Benutzeravatar
schorsch_76
Beiträge: 2535
Registriert: 06.11.2007 16:00:42
Lizenz eigener Beiträge: MIT Lizenz

Re: C++11: user defined literals

Beitrag von schorsch_76 » 26.06.2014 07:16:35

Klar habe ich diese Warnung des Kompilers auch gesehen. Aber hey, "just put an underscore in front of it and be happy!" ;)

wanne
Moderator
Beiträge: 7448
Registriert: 24.05.2010 12:39:42

Re: C++11: user defined literals

Beitrag von wanne » 26.06.2014 08:45:22

schorsch_76 hat geschrieben:Mit diesen user defined literals passiert alles zur Compiletime, es braucht nicht mehr Zyklen und mehr Speicher auf dem Target, kann damit auf auf embedded Systemen genutzt werden.

Das geht sicher nicht mit plain C
Ich würde sagen, alles was zur compiltime geht, geht auch mit
typedef time und
#define min *60

Hie die ensprechende C-Variante:

Code: Alles auswählen

typedef float time;
typedef float speed;

#define h *60*60
#define m *1
#define s *1
#define min *60
#define km *1000

int main(int argc, char** argv)
{
   time t = 1.0 s;
   speed s1 = 100.0 m / 9.8 s; // very fast for a human

   speed s2 = 1.2 km / 0.5 h; // slow going
   speed s3 = 1.2 km / 30.0 min; // the same speed

   return 0;
}
Und siehe da: DIe C++-Variante ist um deutlich über ein viertel größer. Währe interessant wie das dann mit einer ausgabe läuft. Leider scheint sich die iosream nicht mit deinem Programm zu vertragen.

PS: Mir ist natürlich bewusst dass der eigentlich schöne Teil "// speed s2 = 100 / 9.8s; // error" in C nicht funktioniert. Aber dass es ohne overhead ist stimmt einfach nicht.
rot: Moderator wanne spricht, default: User wanne spricht.

Benutzeravatar
bmario
Beiträge: 1256
Registriert: 05.09.2007 12:15:47
Lizenz eigener Beiträge: MIT Lizenz
Wohnort: Dresden

Re: C++11: user defined literals

Beitrag von bmario » 26.06.2014 10:37:37

schorsch_76 hat geschrieben:Klar habe ich diese Warnung des Kompilers auch gesehen. Aber hey, "just put an underscore in front of it and be happy!" ;)
Du solltest die Warnung ernst nehmen, wenn ich mich recht erinnre bringt C++14 "foo"s mit, als std::string (bzw. string_view, da streiten sie wohl noch drum).
wanne hat geschrieben:
schorsch_76 hat geschrieben:Mit diesen user defined literals passiert alles zur Compiletime, es braucht nicht mehr Zyklen und mehr Speicher auf dem Target, kann damit auf auf embedded Systemen genutzt werden.

Das geht sicher nicht mit plain C
Ich würde sagen, alles was zur compiltime geht, geht auch mit
typedef time und
#define min *60

Hie die ensprechende C-Variante:

Code: Alles auswählen

typedef float time;
typedef float speed;

#define h *60*60
#define m *1
#define s *1
#define min *60
#define km *1000

int main(int argc, char** argv)
{
   time t = 1.0 s;
   speed s1 = 100.0 m / 9.8 s; // very fast for a human

   speed s2 = 1.2 km / 0.5 h; // slow going
   speed s3 = 1.2 km / 30.0 min; // the same speed

   return 0;
}
Und siehe da: DIe C++-Variante ist um deutlich über ein viertel größer. Währe interessant wie das dann mit einer ausgabe läuft. Leider scheint sich die iosream nicht mit deinem Programm zu vertragen.

PS: Mir ist natürlich bewusst dass der eigentlich schöne Teil "// speed s2 = 100 / 9.8s; // error" in C nicht funktioniert. Aber dass es ohne overhead ist stimmt einfach nicht.
Der ganze Punkt an dem Beispiel ist eben nicht, dass man die Literale in die Grundeinheit umrechnet, sondern das man damit stark Typisiert ist. Und daraus ergibt sich, dass der Compiler zur Compilezeit checken kann, ob man valide Rechnungen da stehen hat oder nicht. Und das kostet halt keinen Laufzeitoverhead. Zugegeben, du schreibst mehr Code, aber deshalb auf solche Hilfen verzichten, wenn es drauf an kommt? Zumal man das mehr an Code relative zum restlichen Code sehen muss. In einem Projekt mit 100k LoC fallen die paar Zeilen mehr oder weniger gar nicht auf.

Und für die Ausgabe müsstest du einfach std::ostream& operator<<(std::ostream&, T) fr T gleich speed und time überladen.
Nichts zu tun ist viel besser,
als mit viel Mühe nichts zu schaffen. - Laotse

Benutzeravatar
schorsch_76
Beiträge: 2535
Registriert: 06.11.2007 16:00:42
Lizenz eigener Beiträge: MIT Lizenz

Re: C++11: user defined literals

Beitrag von schorsch_76 » 26.06.2014 11:35:47

bmario hat geschrieben:
schorsch_76 hat geschrieben:Klar habe ich diese Warnung des Kompilers auch gesehen. Aber hey, "just put an underscore in front of it and be happy!" ;)
Du solltest die Warnung ernst nehmen, wenn ich mich recht erinnre bringt C++14 "foo"s mit, als std::string (bzw. string_view, da streiten sie wohl noch drum).
Hast ja recht, die Warnung sollte man ernst nehmen.

@wanne: Es geht ja eben exakt darum, dass zur Compiletime ein Fehler kommt. Genau das ist der springende Punkt wie mario schon schrieb. Es ist kein Overhead zur Runtime. Zur Compiletime ist es mir egal, wenn dadurch garantiert wird, das ich die Einheiten richtig verwurste.

wanne
Moderator
Beiträge: 7448
Registriert: 24.05.2010 12:39:42

Re: C++11: user defined literals

Beitrag von wanne » 26.06.2014 11:47:38

bmario hat geschrieben:Der ganze Punkt an dem Beispiel ist eben nicht, dass man die Literale in die Grundeinheit umrechnet, sondern das man damit stark Typisiert ist.
Das erledigt in meinem Programm lint. (kp. warum gcc keine warnungen für falsch typzuweisungen einbaut.) Wenn man das direkt im GCC haben will, kann man structs drumrum bauen.
bmario hat geschrieben:Zugegeben, du schreibst mehr Code
Darum geht es nicht. Das Compilierte Programm ist größer. Der Code währe es um ein vielfaches. Und das habe ich nur angemerkt weil der Verweis von schorsch_76 auf C eindeutig auf einen anderen Thread anspielte in dem er behauptete, dass C++ keinen Overhead erzeugen würde und man C besser ganz abschaffen sollte. Das ist einfach schlicht falsch. Es ist sinnvoll eine wohldefinierte Sprache zu haben, die eben ein paar weniger features hat und dafür bei normaler Nutzung effizient ist.
bmario hat geschrieben:Und für die Ausgabe müsstest du einfach std::ostream& operator<<(std::ostream&, T) fr T gleich speed und time überladen.
Nö, will schon nicht mehr compilieren sobald ich die lib einbinde. (Also noch gar keine ausgabe mache.)
rot: Moderator wanne spricht, default: User wanne spricht.

wanne
Moderator
Beiträge: 7448
Registriert: 24.05.2010 12:39:42

Re: C++11: user defined literals

Beitrag von wanne » 26.06.2014 11:49:08

schorsch_76 hat geschrieben:Es ist kein Overhead zur Runtime.
Lass beide Programme laufen guck dir den Speicherverbrauch an und dann erklärst du mir das nochmal von wegen kein Overhead zur laufzeit...
rot: Moderator wanne spricht, default: User wanne spricht.

Benutzeravatar
schorsch_76
Beiträge: 2535
Registriert: 06.11.2007 16:00:42
Lizenz eigener Beiträge: MIT Lizenz

Re: C++11: user defined literals

Beitrag von schorsch_76 » 26.06.2014 11:57:36

Die umrechnung der Einheiten passiert im compiler und nicht zur Laufzeit. Das garantiert constexpr. Ja, wenn ich die STL dazu linke ist das Programm größer.

@wanne: Bin mir nicht sicher, aber ich denke der gcc 4.7 von wheezy kann das nicht. Ich hab hier gcc 4.8.1 welcher das unterstützt.

Ich habe auch nie behauptet man solle C ganz abschaffen! Kannst gerne versuchen mir die Stelle im Forum zu zeigen. DAS habe ich nicht gesagt. Ich sagte man kann in C++ das gleiche und mehr machen was man in C machen kann. Auch habe ich dich nicht gezwungen C++ zu lernen, C zu vergessen oder in C++ zu arbeiten!

Ich habe nur gezeigt, das C++ etwas kann, was C eben nicht kann. Typsichere user-defined literals.

Benutzeravatar
bmario
Beiträge: 1256
Registriert: 05.09.2007 12:15:47
Lizenz eigener Beiträge: MIT Lizenz
Wohnort: Dresden

Re: C++11: user defined literals

Beitrag von bmario » 26.06.2014 12:10:57

wanne hat geschrieben:
schorsch_76 hat geschrieben:Es ist kein Overhead zur Runtime.
Lass beide Programme laufen guck dir den Speicherverbrauch an und dann erklärst du mir das nochmal von wegen kein Overhead zur laufzeit...
Vergleiche doch mal:
http://goo.gl/NoHbrV

http://goo.gl/CGFsRm

Dieser Overhead der C++ Version ist schon ungeheuerlich!

Was du bezüglich Speicherverbrauch siehst, ist halt einfach die libstdc++. Wenn du bzgl. des Speicherverbrauchs so stark eingeschränkt bist, dann gibt es a) vermutlich eine schlankere stdlib oder b) du musst dich ohnehin mehr anstrengen. Alternativ kannst du auch ganz ohne stdlib bauen - dann kannst du im übrigen trotzdem genau dieses Sprachfeature nutzen ;) -
Nichts zu tun ist viel besser,
als mit viel Mühe nichts zu schaffen. - Laotse

Benutzeravatar
peschmae
Beiträge: 4844
Registriert: 07.01.2003 12:50:33
Lizenz eigener Beiträge: MIT Lizenz
Wohnort: nirgendwo im irgendwo

Re: C++11: user defined literals

Beitrag von peschmae » 26.06.2014 12:42:38

Ich finds auf jeden Fall einen guten Schritt; gerade die Compile-Time Geschichten mit templates und constexpr sind für mich wichtige Vorteile von C++. Präprozessorgeschichten haben immer irgendwelche dummen Seiteneffekte die einem das Leben schwer machen - hab gerade gestern einen halben Tag damit verbraten einen solchen aufzuspüren... :(

Dass man sich die Standardlibrary sparen sollte wenn das zuviel Overhead hat für eine bestimmte Anwendung ist ja wohl klar, und hat erst mal nicht so viel mit der Frage C/C++ zu tun... - der einzige Unterschied ist da am Ende wie komplex der Compiler ist.

MfG Peschmä
"er hätte nicht in die usa ziehen dürfen - die versauen alles" -- Snoopy

wanne
Moderator
Beiträge: 7448
Registriert: 24.05.2010 12:39:42

Re: C++11: user defined literals

Beitrag von wanne » 26.06.2014 12:42:57

bmario hat geschrieben:Vergleiche doch mal:
http://goo.gl/NoHbrV

http://goo.gl/CGFsRm
Die links funktionieren nicht. Verm. weil ich nicht deine Cookies habe.
bmario hat geschrieben:Dieser Overhead der C++ Version ist schon ungeheuerlich!
Wie gesagt 28% am Binary.
bmario hat geschrieben:Was du bezüglich Speicherverbrauch siehst, ist halt einfach die libstdc++.
Ja eben.
bmario hat geschrieben:vermutlich eine schlankere stdlib
Wirst du für C++ nie in den Bereich bekommen, wo C hinkommt. Das ist wie wenn man einen 12 Tonner mit einem Elektrofahrrad vergleicht. Natürlich kann man auch beim typischen 12 Tonner Spritt und Abgase spraen und Agiler werden.
Für die Fortbewegung in der Altstadt ist jeder 12 Tonner einfach das falsche Gefährt. Auch wenn es viel geschickter ist, dass man da nochmal einen Schrank einladen kann und wenn du Gegen die Mauer fährst ist er auch viel sicherer.
bmario hat geschrieben:Alternativ kannst du auch ganz ohne stdlib bauen
Ich kann auch einfach int main() { return 0; } machen. Macht auch das gleiche wie das genannte Programm.
rot: Moderator wanne spricht, default: User wanne spricht.

Benutzeravatar
peschmae
Beiträge: 4844
Registriert: 07.01.2003 12:50:33
Lizenz eigener Beiträge: MIT Lizenz
Wohnort: nirgendwo im irgendwo

Re: C++11: user defined literals

Beitrag von peschmae » 26.06.2014 12:49:03

Also gegen die Mauer fahren ist mit Fahrrad und 12-Tönner etwa gleich schwierig, und sicherer ist weder das eine noch das andere ;)

MfG Peschmä
"er hätte nicht in die usa ziehen dürfen - die versauen alles" -- Snoopy

Benutzeravatar
schorsch_76
Beiträge: 2535
Registriert: 06.11.2007 16:00:42
Lizenz eigener Beiträge: MIT Lizenz

Re: C++11: user defined literals

Beitrag von schorsch_76 » 26.06.2014 12:51:38

@bmario: Kannst du Screenshots einstellen? Danke :)

Benutzeravatar
schorsch_76
Beiträge: 2535
Registriert: 06.11.2007 16:00:42
Lizenz eigener Beiträge: MIT Lizenz

Re: C++11: user defined literals

Beitrag von schorsch_76 » 26.06.2014 13:17:17

Ich hab hier mit meinem gcc-4.8.1 die beiden Programme assembliert.

C:

Code: Alles auswählen

gcc c-version.c -O2 -S
Src: NoPaste-Eintrag37855
Assembly: NoPaste-Eintrag37856

C++11:

Code: Alles auswählen

g++ -std=c++11 cpp-version.cpp -O2 -S
Src: NoPaste-Eintrag37857
Assembly: NoPaste-Eintrag37858

Edit: Tags

Benutzeravatar
bmario
Beiträge: 1256
Registriert: 05.09.2007 12:15:47
Lizenz eigener Beiträge: MIT Lizenz
Wohnort: Dresden

Re: C++11: user defined literals

Beitrag von bmario » 26.06.2014 18:01:11

wanne hat geschrieben:
bmario hat geschrieben:Vergleiche doch mal:
http://goo.gl/NoHbrV

http://goo.gl/CGFsRm
Die links funktionieren nicht. Verm. weil ich nicht deine Cookies habe.
Ja sry, ich dachte "Permalink" erstellt auch solch einen...
schorsch_76 hat geschrieben:@bmario: Kannst du Screenshots einstellen? Danke :)
Der Output kommt deinem Ergebnis gleich.

Zu dem Rest sag ich nichts, mit Gläubigen kann man nicht argumentieren.
Nichts zu tun ist viel besser,
als mit viel Mühe nichts zu schaffen. - Laotse

wanne
Moderator
Beiträge: 7448
Registriert: 24.05.2010 12:39:42

Re: C++11: user defined literals

Beitrag von wanne » 26.06.2014 19:48:26

schorsch_76 hat geschrieben:Ich hab hier mit meinem gcc-4.8.1 die beiden Programme assembliert.
Nein! :facepalm:
Du hast dieses Programm assembliert:

Code: Alles auswählen

int main(){ return 0;}
Da du deinen ganzen schönen C++-foo nie benutzt hast hat dir das die Optimierung vom Compiler natürlich rausgeworfen bevor da irgend was übersetzt wurde. Solange jede effektiv übersetzte Zeile C ist wird dir gcc und g++ natürlich den gleichen code raushauen.

Dein Programm assembliren tust du damit:

Code: Alles auswählen

g++ -std=c++11 cpp-version.cpp -S
BTW: interessanter weise ist das C-Programm wesentlich effizienter, wenn man gcc 4.7.2 statt 4.8.1 nimmt. Dann spart es sich den unnötigen function call für main.
rot: Moderator wanne spricht, default: User wanne spricht.

Benutzeravatar
schorsch_76
Beiträge: 2535
Registriert: 06.11.2007 16:00:42
Lizenz eigener Beiträge: MIT Lizenz

Re: C++11: user defined literals

Beitrag von schorsch_76 » 26.06.2014 20:37:18

Dann geben wir halt S3 mit printf aus (es geht hier um die literals und nicht die STL). In beiden Sprachen ...

C:
Src: NoPaste-Eintrag37859
Assembly: NoPaste-Eintrag37860

C++:
Src: NoPaste-Eintrag37861
Assembly: NoPaste-Eintrag37862

Und jetzt sieh dir den main an:
C assembly hat geschrieben: main:
.LFB24:
.cfi_startproc
subq $8, %rsp
.cfi_def_cfa_offset 16
movl $.LC1, %esi
movl $1, %edi
movsd .LC0(%rip), %xmm0
movl $1, %eax
call __printf_chk
xorl %eax, %eax
addq $8, %rsp
.cfi_def_cfa_offset 8
ret
.cfi_endproc
C++ assembly hat geschrieben: main:
.LFB55:
.cfi_startproc
subq $8, %rsp
.cfi_def_cfa_offset 16
movl $.LC1, %esi
movl $1, %edi
movsd .LC0(%rip), %xmm0
movl $1, %eax
call __printf_chk
xorl %eax, %eax
addq $8, %rsp
.cfi_def_cfa_offset 8
ret
.cfi_endproc
Ich seh keinen unterschied .... du?

EDIT:
Da fällt mir auf .. die C-Version sagt, das langsames gehen 2400 m/s wäre und die C++ Version sagt 0.6667 m/s ... Das ist exakt das was diese Literals verhindern sollen.

charno
Beiträge: 636
Registriert: 28.06.2004 20:24:34

Re: C++11: user defined literals

Beitrag von charno » 26.06.2014 20:54:50

schorsch_76 hat geschrieben:EDIT:
Da fällt mir auf .. die C-Version sagt, das langsames gehen 2400 m/s wäre und die C++ Version sagt 0.6667 m/s ... Das ist exakt das was diese Literals verhindern sollen.
Ich würde sagen hier wurde ein Sieger gefunden :lol:
"Wer sich nicht bewegt, spürt seine Fesseln nicht." - Rosa Luxemburg

Benutzeravatar
schorsch_76
Beiträge: 2535
Registriert: 06.11.2007 16:00:42
Lizenz eigener Beiträge: MIT Lizenz

Re: C++11: user defined literals

Beitrag von schorsch_76 » 26.06.2014 22:55:16

Und hier noch ein kleiner Nachtisch:

Code: Alles auswählen

gcc c-version.c -s -O2 -o vc
gcc -std=c++11 cpp-version.cpp -s -O2 -o vcpp
ls -la 
drwxr-xr-x 2 georg users 4096 26. Jun 22:53 .
drwxr-xr-x 4 georg users 4096 26. Jun 20:26 ..
-rw-r--r-- 1 georg users  392 26. Jun 20:28 c-version.c
-rw-r--r-- 1 georg users  749 26. Jun 20:29 c-version.s
-rw-r--r-- 1 georg users 1979 26. Jun 20:27 cpp-version.cpp
-rw-r--r-- 1 georg users  762 26. Jun 20:28 cpp-version.s
-rwxr-xr-x 1 georg users 6224 26. Jun 22:49 vc
-rwxr-xr-x 1 georg users 6224 26. Jun 22:53 vcpp
-s Remove all symbol table and relocation information from the executable.
-s wirft nur die Symbole raus. g++ linkt immer die stdc++ dazu.

Code: Alles auswählen

georg@machariel ~/Downloads/tmp $ hexdump -C vc > vc.txt
georg@machariel ~/Downloads/tmp $ hexdump -C vcpp > vcpp.txt
georg@machariel ~/Downloads/tmp $ diff vc.txt vcpp.txt 
102,103c102,103
< 00000650  01 00 02 00 53 70 65 65  64 20 73 33 3a 20 25 66  |....Speed s3: %f|
< 00000660  00 00 00 00 00 00 00 00  00 00 00 00 00 c0 a2 40  |...............@|
---
> 00000650  01 00 02 00 53 70 65 65  64 20 53 33 3a 20 25 66  |....Speed S3: %f|
> 00000660  00 00 00 00 00 00 00 00  55 55 55 55 55 55 e5 3f  |........UUUUUU.?|
Damit sollte das Thema durch sein.

wanne
Moderator
Beiträge: 7448
Registriert: 24.05.2010 12:39:42

Re: C++11: user defined literals

Beitrag von wanne » 27.06.2014 00:13:20

schorsch_76 hat geschrieben:-s wirft nur die Symbole raus.
Ja.
Aber dein -O2 hst du immer noch drin und der wirft dir weiterhin den gesamten C++-Code raus. Überig bleibt das C-printf (Dass man im übrigen so in C++11 und neuer nicht mehr benutzen soll.) mit einer Konstante.
rot: Moderator wanne spricht, default: User wanne spricht.

Benutzeravatar
schorsch_76
Beiträge: 2535
Registriert: 06.11.2007 16:00:42
Lizenz eigener Beiträge: MIT Lizenz

Re: C++11: user defined literals

Beitrag von schorsch_76 » 27.06.2014 07:30:06

wanne hat geschrieben:
schorsch_76 hat geschrieben:-s wirft nur die Symbole raus.
Ja.
Aber dein -O2 hst du immer noch drin und der wirft dir weiterhin den gesamten C++-Code raus. Überig bleibt das C-printf (Dass man im übrigen so in C++11 und neuer nicht mehr benutzen soll.) mit einer Konstante.
Ganz genau. Jetzt hast du es begriffen. Der ganze Aufwand war es, Typsicher den Compiler die Berechnung der Konstante machen zu lassen (constexpr) aber zur Laufzeit einfach einen double zu verarbeiten.

Der Kompiler garantiert mir, dass ich nur Berechnungen mache, welche auch Sinn machen (welche ich ihm natürlich mitteilen muss). Ich kann einfach einer Geschwindigkeit keinen Wert in sec zuweisen (was mit den C typedefs keinen Fehler erzeugt). Das ist genau das was verhindert werden soll, sowie der Umrechnungsfehler mit den Makros.

Das mit dem printf habe ich nur genutzt um beide Teile vergleichbar zu halten und nur auf das Feature zu gehen.

Antworten