C++11: user defined literals

Vom einfachen Programm zum fertigen Debian-Paket, Fragen rund um Programmiersprachen, Scripting und Lizenzierung.
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: 2544
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: 2544
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: 7465
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: 2544
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: 2544
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: 7465
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: 2544
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.

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

Re: C++11: user defined literals

Beitrag von wanne » 27.06.2014 09:11:06

schorsch_76 hat geschrieben:Das mit dem printf habe ich nur genutzt um beide Teile vergleichbar zu halten und nur auf das Feature zu gehen.
Nein. War es nicht. Ist aber egel.
schorsch_76 hat geschrieben: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.
Meine Programme schmeisen aber typischerweise keine Statischen ergebnisse. Dazu fange ich normalerweise nicht an nen Compiler anzuwerfen. Soche Programme sind im Normalfall Sinnlos. Wenn ich die durchschnittsgeschwiniigkeit über eine Stunde ausrechen will schreibe ich garantiert keine 85 Zeilen Code. – Das ist Fehleranfällig.
rot: Moderator wanne spricht, default: User wanne spricht.

Benutzeravatar
schorsch_76
Beiträge: 2544
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 11:09:54

Hier ist noch ein echtes nützliches Beispiel das nicht nur user defined literals zeigt, sondern type rich interface.

NoPaste-Eintrag37863

Damit kann ich, auch auf einem embedded Device, sicher stellen, dass ich immer richtig digits zu Spannung / Strom wandle. Im Kompilat rechne ich auch hier nur mit double. Der Compiler stellt sicher, dass ich ein "digit_from_dac2" nicht in eine Spannung wandle.

Benutzeravatar
schorsch_76
Beiträge: 2544
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 13:48:29

Oh ... noch ein Nachtrag:

NoPaste-Eintrag37864

Code: Alles auswählen

g++ -std=c++11 -O2 -s electric-conversion.cpp -o electric-conversion
georg@machariel ~/Dokumente/Entwicklung/c++11-snipets/type-rich-interface $ ls -la
insgesamt 20
drwxr-xr-x 2 georg users 4096 27. Jun 13:44 .
drwxr-xr-x 5 georg users 4096 27. Jun 13:00 ..
-rwxr-xr-x 1 georg users 6264 27. Jun 13:44 electric-conversion
-rw-r--r-- 1 georg users 3545 27. Jun 13:42 electric-conversion.cpp
georg@machariel ~/Dokumente/Entwicklung/c++11-snipets/type-rich-interface $ ldd electric-conversion
        linux-vdso.so.1 (0x00007fff25388000)
        libstdc++.so.6 => /usr/lib/gcc/x86_64-pc-linux-gnu/4.9.0/libstdc++.so.6 (0x00007fd2b3b61000)
        libm.so.6 => /lib64/libm.so.6 (0x00007fd2b3867000)
        libgcc_s.so.1 => /usr/lib/gcc/x86_64-pc-linux-gnu/4.9.0/libgcc_s.so.1 (0x00007fd2b3650000)
        libc.so.6 => /lib64/libc.so.6 (0x00007fd2b32a0000)
        /lib64/ld-linux-x86-64.so.2 (0x00007fd2b3e76000)
Auch die Version welche gegen die libstc++ linkt ist nicht groß.

Wenn ich versuche vom adc2 eine Spannung zu lesen, kommt

Code: Alles auswählen

 g++ -std=c++11 -O2 -s electric-conversion.cpp -o electric-conversion
electric-conversion.cpp: In Funktion »int main(int, char**)«:
electric-conversion.cpp:148:26: Fehler: Umwandlung von »{anonym}::digits_from_adc2« in nicht-skalaren Typen »uri::U {aka uri::Value<uri::Unit<1, 0> >}« angefordert
  U u3 = digits_from_adc2(); // error 
Das ist dann doch sehr deutlich.

Antworten