Sprachfeatures

Athaba

Libellenliebhaber
Zunächst mal eine Preisfrage an alle C/++-Programmierer. Was tut dieser Code?

Code:
int main() {
   printf("LOL??!");
}

Zu derartigen Features in diversen Sprachen gibt's einen Thread auf Stack Overflow (was die Leser von DragonFly Digest aber sicher schon wissen). Das ist ziemlich interessant, weil es einiges gibt wo man leicht in die Falle tappen kann, scheinbar vor allem mit JavaScript.
 
Zunächst mal eine Preisfrage an alle C/++-Programmierer. Was tut dieser Code?

Mir persönlich erschließt sich nicht der Grund bzw. Ziel deiner Frage. Dass keine Programmiersprache perfekt ist und es immer einige Seiteneffekte gibt, sollte jedem klar sein.

Ein weiteres Beispiel sind die Shift-Operationen. Die Funktionsweise ist abhängig von der verbauten CPU. Beispiel Intel ... (was war da gleich nochmal verbaut, egal) 32bit CPU.

Code:
int8_t a = 0x01;
b = a << 8;
c = a << 32;
Auf meiner damaligen Intel CPU 32bit war b == 0 und C == 1. Das konnte ich in jeder x-beliebigen Sprache testen (C, Java, .NET, ...). Dies kann man in der Doku von Intel nachschlagen. Aber wer denkt da schon dran.

Gruß, Thomas
 
Der Grund für diesen Thread ist einfach, dass ich auf nicht so bekannte Features aufmerksam machen wollte. Ich bin ja ein Perl-Fan und diese Sprache lebt ja quasi davon (ich weiß, viele hassen sie dafür).

Viele Dinge machen Fehler und Bugs oder erlauben eine starke Vereinfachung. In jedem Fall ist es gut darüber Bescheid zu wissen. Selbst wenn man es mal gelernt hat denkt man beim Programmieren im Alltag häufig nicht an irgendwelche Kleinigkeiten.

Der Thread rückt vieles ins Blickfeld, was den einen oder anderen vielleicht verwundert. Ich kannte zum Beispiel JavaScripts == vs ===, das einem als Anfänger Probleme macht, aber vieles war mir neu. Naja, da ich das ohnehin nur clientseitig verwende und da meist CoffeeScript schreibe bleiben mir ein paar Dinge erspart.

Dass man Array in C auf mehrere Arten anschreiben kann wissen wohl auch nicht so viele:
Code:
a[10]
10[a]
 
Ein weiteres Beispiel sind die Shift-Operationen. Die Funktionsweise ist abhängig von der verbauten CPU. Beispiel Intel ... (was war da gleich nochmal verbaut, egal) 32bit CPU.

Code:
int8_t a = 0x01;
b = a << 8;
c = a << 32;
Auf meiner damaligen Intel CPU 32bit war b == 0 und C == 1. Das konnte ich in jeder x-beliebigen Sprache testen (C, Java, .NET, ...). Dies kann man in der Doku von Intel nachschlagen. Aber wer denkt da schon dran.
Deine Begründung ist schlicht falsch.
Ich gehe im Folgenden auf c = a << 32 ein:

C (ISO/IEC 9899:1999 (E) §6.5.7): Ist der linke Operand schmaler als int, so wird er zunächst auf int konvertiert. Dann folgt << und hier sagt die C-Norm, dass deren Verhalten undefiniert ist, falls um die Breite des (evtl. konvertierten) linken Operanden oder mehr geschoben wird. Es wäre also durchaus möglich und von der Norm aus zulässig, wenn c den Wert 42 hat, das Programm an der Stelle einen Segfault verursacht oder dein $HOME gelöscht wird. Üblicherweise wird der Übersetzer den einfachsten Weg wählen und einfach den entsprechenden Maschinenbefehl, bei x86 shl, ausgeben (wenn das ganze nicht eh schon komplett zu einer Konstante gefaltet wird).

Java (JLS 3rd Edition §15.9), .NET (wobei nicht .NET, sondern wohl eher C# und somit ECMA-334 §14.8): Diese definieren ebenfalls eine eventuelle Konversion auf mindestens int (wobei hier die Breite eines int im Gegensatz zu C exakt auf 32 Bit festgelegt ist) und danach passiert ein << um den Wert des rechten Operanden modulo der Breite des (evtl. konvertierten) linken Operanden, also quasi (int)a << (32 % 32) und somit (int)a << 0. Das hat nichts, aber auch gar nichts, mit dem zu tun, was der Prozessor implementiert (nur [mehr oder minder] zufällig verhält sich die shl-Befehl des x86 ebenso).

Es gibt auch Prozessoren, deren Schiftbefehl sich anders verhält, z.B. der PPC64.

Das Nachschlagen der genauen Semantik von b = a << 8, welche stark abhängig vom Typ von b ist, überlasse ich dem geneigten Leser als Übungsaufgabe.
 
Zurück
Oben