mikrocontroller.net

Forum: Compiler & IDEs n++ hier oder dort?


Announcement: there is an English version of this forum on EmbDev.net. Posts you create there will be displayed on Mikrocontroller.net and EmbDev.net.
Autor: Kleiner Hüpfer (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo ich habe eine Anfängerfrage:

X[n++]=n;

oder

X[n]=n++;

was macht den Unterschied?

Autor: Nix (Gast)
Datum:

Bewertung
-4 lesenswert
nicht lesenswert
Nix. Das Verhalten ist equivalent. Der Compiler wird daraus mit hoher 
Wahrscheinlichkeit sogar identischen Assembler-Code erzeugen.

Autor: Kleiner Hüpfer (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Nix schrieb:
> Nix. Das Verhalten ist equivalent. Der Compiler wird daraus mit
> hoher Wahrscheinlichkeit sogar identischen Assembler-Code erzeugen.

Sicher? Ich hätte erwartet das die rechte Seite zuerst ausgeführt würde!

Autor: mh (Gast)
Datum:

Bewertung
2 lesenswert
nicht lesenswert
Kleiner Hüpfer schrieb:
> Hallo ich habe eine Anfängerfrage:
>
> X[n++]=n;
>
> oder
>
> X[n]=n++;
>
> was macht den Unterschied?

Nix schrieb:
> Nix.

Exact! Beies ist undefined behaviour in C und C++. Das sieht man auch an 
den Warnungen die gcc gibt:
xxx.cpp: In function ‘int main()’:
xxx.cpp:5:6: warning: operation on ‘n’ may be undefined [-Wsequence-point]
   X[n++]=n;
     ~^~
xxx.cpp:6:9: warning: operation on ‘n’ may be undefined [-Wsequence-point]
   X[n]=n++;
        ~^~

Autor: Nix (Gast)
Datum:

Bewertung
-7 lesenswert
nicht lesenswert
Das ++ nach der Variable bedeutet: "Inkrementiere nach der 
Zeile/Anweisung".

Autor: Paul (Gast)
Datum:

Bewertung
1 lesenswert
nicht lesenswert
Kleiner Hüpfer schrieb:
> Sicher? Ich hätte erwartet das die rechte Seite zuerst ausgeführt würde!

Das währe dann der Unterschied zwischen n++ und ++n

Autor: Oliver S. (oliverso)
Datum:

Bewertung
5 lesenswert
nicht lesenswert
Nix schrieb:
> Nix.

Das ist richtig.

Nix schrieb:
> Der Compiler wird daraus mit hoher
> Wahrscheinlichkeit sogar identischen Assembler-Code erzeugen.

Das ist möglich, wäre aber Zufall.

Da sich in beiden Varianten kein Sequence-Point zwischen n und n++ 
befindet, sind beide Varianten nicht zulässig, und resultieren in 
undefined behaviour.

Oliver

Autor: Mac (Gast)
Datum:

Bewertung
2 lesenswert
nicht lesenswert
Beides hat undefinieres Verhalten, weil Seiteneffekte (++ in diese 
Fall) erst nach einem Sequenzpunkt definiert sind. D.h. möglicherweise 
ist n erst nach der Zuweisung implementiert, möglicherweise aber auch 
vorher.

Autor: Mac (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
* inkrementiert

Doofes handy

Autor: Kleiner Hüpfer (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Paul schrieb:
> das währe dann der Unterschied zwischen n++ und ++n

äh nö, bei ++n wird vorher incrementiert.
Bei nur++ nachher.

Autor: Kleiner Hüpfer (Gast)
Datum:

Bewertung
1 lesenswert
nicht lesenswert
Mac schrieb:
> Beides hat undefinieres Verhalten, weil Seiteneffekte (++ in diese
> Fall) erst nach einem Sequenzpunkt definiert sind. D.h. möglicherweise
> ist n erst nach der Zuweisung implementiert, möglicherweise aber auch
> vorher.

Also sollte man besser :

x[n]=n;
n++;

schreiben und nicht versuchen alles in eine Zeile zu quetschen...

Autor: Michael B. (laberkopp)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Nix schrieb:
> Das ++ nach der Variable bedeutet: "Inkrementiere nach der
> Zeile/Anweisung".

Nein,
es heisst: Inkrementiere irgendwann nach diesem Zugriff

Autor: Oliver S. (oliverso)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Sollte man in dem Fall auf jeden Fall tun.

Da die Zeile allerdings mit an Sicherheit grenzender Wahrscheinlichkeit 
in einer for- oder while-Schleife steht, kannst du das n++ auch dort 
hinein packen.

Oliver

Autor: Jobst Q. (joquis)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Man muss nicht jeden Unsinn machen, den man darf.

Also schreib entweder

X[n]=n;n++;

oder

n++;X[n]=n;

oder

X[n+1]=n;n++;

je nachdem, was das Programm tun soll.

Dann gibt es keine Missverständnisse mit dem Compiler.

Autor: Amateur (Gast)
Datum:

Bewertung
-8 lesenswert
nicht lesenswert
Eigentlich sind das einfachste C-Grundlagen.
----------------
Vorher Var  == ??
Vorher n    == 2;
Var = n++;
Nachher Var == 2;
Nachher n   == 3;

----------------
Vorher Var  == ??
Vorher n    == 2;
Var = ++n;
Nachher Var == 3;
Nachher n   == 3;

Die Stichworte hierzu lauten post- bzw. pre-imcrement.

Autor: Jobst Q. (joquis)
Datum:

Bewertung
1 lesenswert
nicht lesenswert
Kleiner Hüpfer schrieb:
> schreiben und nicht versuchen alles in eine Zeile zu quetschen...

Die Zeile hat meist keine Bedeutung in C. Aber das ';'.

: Bearbeitet durch User
Autor: Michael R. (fisa)
Datum:

Bewertung
4 lesenswert
nicht lesenswert
Amateur schrieb:
> Eigentlich sind das einfachste C-Grundlagen.

Eigentlich solltest du nochmal über das Problem nachdenken ;-)

Autor: Martin B. (ratazong)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich wäre nie auf die Idee gekommen, solche Zeilen zu schreiben. Also 
habe ich es mal mit dem gcc ausprobiert.

#include <stdio.h>

void main(int argc,char **argv){
int X[5] ={-1,-1,-1,-1,-1};
int i;

i=2;
X[i++]=i;

X[i]=i++;
printf("\n%d %d %d %d %d\n",X[0],X[1],X[2],X[3],X[4]);

}

output war:
-1 -1 3 -1 3

X[0],X[1] wurden nie angefasst
X[2] = 3 !  addressiert wurde erwartungsgemäß X[2], aber drin steht eine 
3, d.h. i wurde vorher inkrementiert.
X[3] wurde nie angefasst
X[4] = 3; (=i++; ergibt nicht inkrementierten Wert, bei der Aressierung 
wird der inkrementierte Wert benutzt)

Hätte ich so nicht erwartet, aber ich hätte diese Zeilen auch nie 
geschrieben.

Autor: Oliver S. (oliverso)
Datum:

Bewertung
4 lesenswert
nicht lesenswert
Martin B. schrieb:
> Hätte ich so nicht erwartet,

Wenn du nochmals über den Begriff "undefined behaviour" nachdenkst, 
sollte dir einiges klarer werden.

Aus der C FAQ:

"The C FAQ defines “undefined behavior” like this:

    Anything at all can happen; the Standard imposes no requirements. 
The program may fail to compile, or it may execute incorrectly (either 
crashing or silently generating incorrect results), or it may 
fortuitously do exactly what the programmer intended."

Oliver

: Bearbeitet durch User
Autor: Programmiersprachentheaterintendant (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Also schreib entweder
>
> X[n]=n;n++;
>
> oder
>
> n++;X[n]=n;
>
> oder
>
> X[n+1]=n;n++;
>
> je nachdem, was das Programm tun soll.

Exakt. Was ist eigentlich damit gewollt?
- Arrayelement beschreiben mit Wert==Index?
- Arrayelement beschreiben mit Wert-eins-mehr-als-Index?
- Danach soll Index aufs nächste Arrayelement "zeigen"? Warum? 
Schleifenkörper? ächste Instruktion lautet wie?

Autor: Luther B. (luther-blissett)
Datum:

Bewertung
3 lesenswert
nicht lesenswert
Martin B. schrieb:
> Ich wäre nie auf die Idee gekommen, solche Zeilen zu schreiben. Also
> habe ich es mal mit dem gcc ausprobiert.


$ gcc -O2 u.c -o u ; ./u

-1 -1 3 -1 3

$ clang u.c -o u ; ./u

-1 -1 2 -1 3

So sieht es aus, das undefinierte Verhalten.

Autor: Luther B. (luther-blissett)
Datum:

Bewertung
3 lesenswert
nicht lesenswert
Amateur schrieb:
> Die Stichworte hierzu lauten post- bzw. pre-imcrement.

Nein, das Stichwort lautet "Sequence Point". Siehe 
http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1256.pdf (Abschnitt 
5.1.2.3, sowie Annex C)

Autor: Martin B. (ratazong)
Datum:

Bewertung
-1 lesenswert
nicht lesenswert
Luther B. schrieb:
> So sieht es aus, das undefinierte Verhalten.


Da macht ja jeder was er will! :-)

Doof am gcc: Der warnt davor nicht in der Standarteinstellung. Das 
braucht -Wall o.ä.

Autor: Luther B. (luther-blissett)
Datum:

Bewertung
1 lesenswert
nicht lesenswert
Martin B. schrieb:
> Luther B. schrieb:
>> So sieht es aus, das undefinierte Verhalten.
>
>
> Da macht ja jeder was er will! :-)
>
> Doof am gcc: Der warnt davor nicht in der Standarteinstellung. Das
> braucht -Wall o.ä.

$ gcc -O2 u.c -o u ; ./u

-1 -1 3 -1 3

$ clang u.c -o u ; ./u

-1 -1 2 -1 3

$ tcc u.c -o u ; ./u # https://bellard.org/tcc/

-1 -1 3 3 -1

(Visual Studio 2017):

-1 -1 2 3 -1

: Bearbeitet durch User
Autor: Dirk B. (dirkb2)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hängt das Ergebnis beim gcc von der Optimierungsstufe ab?

Autor: Luther B. (luther-blissett)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Dirk B. schrieb:
> Hängt das Ergebnis beim gcc von der Optimierungsstufe ab?

In diesem Beispiel kommt bei meinem Compiler das gleiche raus, das ist 
aber nicht immer so. Siehe z.B. damals, als der GCC-Optimierer die 
kaputten overflow checks wegoptimiert hat => 
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=30475

Autor: Tom (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Martin B. schrieb:
> Doof am gcc: Der warnt davor nicht in der Standarteinstellung. Das
> braucht -Wall o.ä.

Da ist clang (wie meistens) überlegen:
$ clang 1.c

1.c:3:1: warning: return type of 'main' is not 'int' [-Wmain-return-type]
void main(int argc,char **argv){
^
1.c:3:1: note: change return type to 'int'
void main(int argc,char **argv){
^~~~
int
1.c:8:4: warning: unsequenced modification and access to 'i' [-Wunsequenced]
X[i++]=i;
   ^   ~
1.c:10:7: warning: unsequenced modification and access to 'i' [-Wunsequenced]
X[i]=i++;
  ~   ^
3 warnings generated.

Autor: Michael R. (fisa)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Tom schrieb:
> Da ist clang (wie meistens) überlegen:

wie genau meinst du "meistens"?

und, Nebenschauplatz: wie weit ist clang für zB AVR?

ich wollte das peopachten, habs aber vom Radar verloren

Autor: Heiko L. (zer0)
Datum:

Bewertung
-4 lesenswert
nicht lesenswert
Luther B. schrieb:
> So sieht es aus, das undefinierte Verhalten.

Dafür, dass sie es sich aussuchen konnten, wie es aussehen soll, haben 
die aber ziemlich bescheuert gewählt. Naja. Jedem das seine...

Autor: A. S. (achs)
Datum:

Bewertung
1 lesenswert
nicht lesenswert
Heiko L. schrieb:
>> So sieht es aus, das undefinierte Verhalten.
>
> Dafür, dass sie es sich aussuchen konnten, wie es aussehen soll, haben
> die aber ziemlich bescheuert gewählt. Naja. Jedem das seine...

Äh, vermutlich ist Dir dann nicht ganz klar, was undefiniertes Verhalten 
(UB) für "die" bedeutet:

"Das ist so abstrus, dass macht niemand niemals! und wenn doch, dann 
sitzt da ein Volltrottel, dann dürfen alle Dämme brechen, dann tragen 
wir keine Verantwortung mehr, dann können wir auch später noch wahllos 
Bits in irgendwelchen Registern kippen, dann ist der Blödmann selber 
schuld".

UB heisst *NICHT*: "Naja, dies wäre richtig oder das, oder jenes wäre 
OK, also machen wir das so!" Das wäre "Unspecified Behaviour"

Autor: Heiko L. (zer0)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Oh, richtig.
Müssen, sollen, können - alles kein Unterschied, righty right?
Dürfen gäbe es da auch noch.

Natürlich KANN man auch "undefined behaviour" im Sinne des Standards in 
sich konsistent umsetzen. Man MUSS nur nicht, weil der Standard (ließ: 
das absolute Minimum des gerade noch erträglichen) da nicht sagt, dass 
es "implementation defined" ist, wo dann also eine konsistente 
Definition vorliegen MÜSSTE. Da DARF der Compilerbauer dann also auch 
die Festplatte und die GIT-Repos löschen (laut C-Standard jedenfalls).

Gutes Beispiel ist der int-overflow.
0x7fffffff + 1  kann 0x80000000 ergeben. Kann aber aber auch die 
Festplatte löschen. Alles eine Frage des Geschmacks.

: Bearbeitet durch User
Autor: Le X. (lex_91)
Datum:

Bewertung
2 lesenswert
nicht lesenswert
Heiko L. schrieb:
> Natürlich KANN man auch "undefined behaviour" im Sinne des Standards in
> sich konsistent umsetzen.

Wie denn?
Welches Verhalten soll denn der arme Compilerbauer umsetzen wenn nichts 
definiert ist?

Autor: Dumdi D. (dumdidum)
Datum:

Bewertung
1 lesenswert
nicht lesenswert
Le X. schrieb:
> Welches Verhalten soll denn der arme Compilerbauer umsetzen wenn nichts
> definiert ist?

Seine eigene Definition. Bei int overflow koennte man wrapping 
definieren, bei dem Sequencepoint Problen koennte man Auswertung von 
links nach rechts definieren.
Das macht es aber sehr schwer schnelle Optimierer zu schreiben, d.h. es 
wird Geschwindigjeitseinbussen geben.

Autor: Oliver S. (oliverso)
Datum:

Bewertung
1 lesenswert
nicht lesenswert
Dumdi D. schrieb:
> Seine eigene Definition.

Das machen doch auch alle. Denn jeder Compiler bricht ja bei der 
Üebrsetzung der o.a. Zeilen nicht ab, sondern generiert Code. Also gibt 
es intern schon irgendwelche compilerspezifoschen Definitionen, wie 
sowas übersetzt wird. Du bekommst nur nicht gesagt, was für welche...

Oliver

: Bearbeitet durch User
Autor: Heiko L. (zer0)
Datum:

Bewertung
-3 lesenswert
nicht lesenswert
Dumdi D. schrieb:
> Das macht es aber sehr schwer schnelle Optimierer zu schreiben, d.h. es
> wird Geschwindigjeitseinbussen geben.

Wenn man bedenkt, dass man, um garantieren zu können, dass keine 
Festplatten gelöscht würden, vor jeder einzelnen int-Rechenoperation 
prüfen müsste, dass sie keinen Overflow generiert, wäre ich mir da nicht 
sicher.

undefined behaviour: Oh, mein Gott!! Das Ding könnte eine von zwei 
unabhängigen Firmen verifizierte Prüf- und Schutzroutine außer Kraft und 
schwere Maschinerie trotz gedrücktem Not-Aus-Schalter in Gang setzen, 
wenn einmal ein a*b überläuft.
"Aha, c=a*b läuft über. Das merke ich mir mal und - oh: hier diese 
if-Abfrage benutzt c, da setzte ich als Ergebnis mal - hmm, wie ist es 
günstiger - "true" ein. Und hier, diese Abfrage.. Oh oh, "c+10". Das 
macht die Sache jetzt aber nicht besser. Na gut, sagen wir mal, ich habe 
gerade eben INT_MAX für c eingesetzt, was das "true" als Ergebnis 
zulässt und habe jetzt: Tada - Noch einen Overflow! In diesem Fall darf 
ich jetzt nämlich wieder "true" einsetzen und den nachfolgenden Jump 
ausführen, was viel günstiger ist, als dieses "void 
emergency_shutdown()". Jaja, ein einzelner Overflow hätte da nicht 
gereicht. Musste mir Mühe schon geben..."

Autor: Luther B. (luther-blissett)
Datum:

Bewertung
2 lesenswert
nicht lesenswert
Oliver S. schrieb:
> Dumdi D. schrieb:
>> Seine eigene Definition.
>
> Das machen doch auch alle. Denn jeder Compiler bricht ja bei der
> Üebrsetzung der o.a. Zeilen nicht ab, sondern generiert Code. Also gibt
> es intern schon irgendwelche compilerspezifoschen Definitionen, wie
> sowas übersetzt wird. Du bekommst nur nicht gesagt, was für welche...
>
> Oliver

Unterstelle einem Verhalten nicht eine Definition. Es kann reiner Zufall 
sein, was bei der Übersetzung von UB hearuskommt, z.B. kann durch das 
zusammenwirken unabhängiger Optimierungsstufen die Reihenfolge der 
Inkrementierungen innerhalb eines Sequence Points geändert werden. Der 
Compiler muss nur über eine Defintion verfügen, welche gültige 
Reihenfolgen erzeugt, ohne das im Einzelnen klar wäre, welche das in 
einem konkreten Fall ist. Der Compiler könnte also z.B. für eine andere 
CPU eine andere Reihenfolge erzeugen, weil der Optimierer dort anders 
arbeitet. gcc hat z.B. Optimierungen die auf Heuristiken beruhen 
(-fguess-branch-probability) und bei profile-guided Optimierung ist das 
Ergebnis im Grunde zufällig, wenn es von nicht vollständig 
reproduzierbaren Profileruns abhängt.

Und UB kann deine Festplatte löschen:

https://kristerw.blogspot.de/2017/09/why-undefined-behavior-may-call-never.html

Autor: Jobst Q. (joquis)
Datum:

Bewertung
-1 lesenswert
nicht lesenswert
Luther B. schrieb:
> Und UB kann deine Festplatte löschen:
>
> https://kristerw.blogspot.de/2017/09/why-undefined-behavior-may-call-never.html

Dazu muss man die Bombe (system("rm -rf /");) aber schon selbst 
einbauen. Der Compiler macht das nicht.

Autor: Martin H. (horo)
Datum:

Bewertung
-1 lesenswert
nicht lesenswert
Dann nenne die Funktion meinetwegen NotAus(), bei der die Maschine 
destruktiv runtergefahren wird, um z.B. Menschen zu schützen...

Autor: Jobst Q. (joquis)
Datum:

Bewertung
-1 lesenswert
nicht lesenswert
Wie man die Bombe nennt, ist egal. Wer hochgefährliche Sachen schreibt, 
kann die Verantwortung nicht auf den Compiler oder die 
Programmiersprache schieben.

: Bearbeitet durch User
Autor: Der Andere (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Jobst Q. schrieb:
> X[n]=n;n++;
>
> oder
>
> n++;X[n]=n;
>
> oder
>
> X[n+1]=n;n++;

Diesen Unfug auf Teufel komm raus Zeilen sparen zu wollen haben wir 
zuletzt auf einem Commodore CBM 4008 gemacht. Da war das Problem, daß 
der Basic Source Code sonst wegen der Zeilenumbrüche zu groß wurde um 
ins Ram zu passen.

Ich denke doch daß man in heutiger Zeit mit Terabytes an Plattenplatz 
und Gigabytes an RAM die paar carriage return / Line Feed spendieren 
kann um das Progamm eindeutig und lesbar zu machen.

Autor: Oliver S. (oliverso)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Luther B. schrieb:
> Unterstelle einem Verhalten nicht eine Definition. Es kann reiner Zufall
> sein, was bei der Übersetzung von UB hearuskommt,

Genauso war das auch gemeint. Es ist reiner Zufall, was da raus kommt, 
aber es kommt was raus.

Oliver

Autor: Luther B. (luther-blissett)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Jobst Q. schrieb:
> Luther B. schrieb:
>> Und UB kann deine Festplatte löschen:
>>
>> https://kristerw.blogspot.de/2017/09/why-undefined-behavior-may-call-never.html
>
> Dazu muss man die Bombe (system("rm -rf /");) aber schon selbst
> einbauen. Der Compiler macht das nicht.

Es reicht aus, wenn system einen buffer benutzt, der vom User befüllt 
werden kann, UB einen check löscht, was dazu führt, dass system mit dem 
buffer aufgerufen wird. Zahlreiche CVE basieren z.B. auf UB, bei denen 
checks ausser Kraft gesetzt wurde. Hier z.B. sehr ein lehrreiches 
Beispiel:

https://lwn.net/Articles/342330/

Bei UB verwandelt sich potentiell dein ganzer Code in eine Bombe.

Autor: Le X. (lex_91)
Datum:

Bewertung
2 lesenswert
nicht lesenswert
Heiko L. schrieb:
> Gutes Beispiel ist der int-overflow.
> 0x7fffffff + 1  kann 0x80000000 ergeben. Kann aber aber auch die
> Festplatte löschen. Alles eine Frage des Geschmacks.

Heiko L. schrieb:
> Das Ding könnte eine von zwei
> unabhängigen Firmen verifizierte Prüf- und Schutzroutine außer Kraft und
> schwere Maschinerie trotz gedrücktem Not-Aus-Schalter in Gang setzen,
> wenn einmal ein a*b überläuft.

Halt mal lieber ruhig.

Diese blumigen Metaphern wie "Festplatte löschen" oder "Dämonen, die aus 
der Nase fliegen" sind Übertreibungen und dienen lediglich dazu, einem 
Anfänger die Bedeutung von "undefined Behaviour" anschaulich 
nahezubringen.

Dass es in der Praxis keine Implementierung eines C-Compilers gibt der 
dir bei einem signed-overflow die Festplatte löscht weißt du genauso gut 
wie ich.
Keinen Grund, sich deswegen aufzuführen wie ein Gartenschlauch.

Autor: Martin H. (horo)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
C99RationaleV5.10.pdf sagt auf Seite 11:

The terms unspecified behavior, undefined behavior, and 
implementation-defined behavior are used to categorize the result of 
writing programs whose properties the Standard does not, or cannot, 
completely describe.  The goal of adopting this categorization is to 
allow a certain variety among implementations which permits quality of 
implementation to be an active force in the marketplace as well as to 
allow certain popular extensions, without removing the cachet of 
conformance to the Standard.  Informative Annex J of the Standard 
catalogs those behaviors which fall into one of these three categories.

Unspecified behavior gives the implementor some latitude in 
translating programs. This latitude does not extend as far as failing to 
translate the program, however, because all possible behaviors are 
“correct” in the sense that they don’t cause undefined behavior in any 
implementation.

Undefined behavior gives the implementor license not to catch certain 
program errors that are difficult to diagnose. It also identifies areas 
of possible conforming language extension: the implementor may augment 
the language by providing a definition of the officially undefined 
behavior.

Implementation-defined behavior gives an implementor the freedom to 
choose the appropriate approach, but requires that this choice be 
explained to the user. Behaviors designated as implementation-defined 
are generally those in which a user could make meaningful coding 
decisions based on the implementation’s definition. Implementors should 
bear in mind this criterion when deciding how extensive an 
implementation definition ought to be. As with unspecified behavior, 
simply failing to translate the source containing the 
implementation-defined behavior is not an adequate response.

Autor: Oliver S. (oliverso)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Da finde ich den Standard selber klarer formuliert:

undefined behavior
behavior, upon use of a nonportable or erroneous program construct or of 
erroneous data, for which this International Standard imposes no 
requirements
NOTE Possible undefined behavior ranges from ignoring the situation 
completely with unpredictable results, to behaving during translation or 
program execution in a documented manner characteristic of the 
environment (with or without the issuance of a diagnostic message), to 
terminating a translation or execution (with the issuance of a 
diagnostic message).



unspecified behavior
behavior where this International Standard provides two or more 
possibilities and imposes no further requirements on which is chosen in 
any instance
EXAMPLE An example of unspecified behavior is the order in which the 
arguments to a function are evaluated.

Oliver

Autor: Jobst Q. (joquis)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Luther B. schrieb:

> Es reicht aus, wenn system einen buffer benutzt, der vom User befüllt
> werden kann, UB einen check löscht, was dazu führt, dass system mit dem
> buffer aufgerufen wird. Zahlreiche CVE basieren z.B. auf UB, bei denen
> checks ausser Kraft gesetzt wurde. Hier z.B. sehr ein lehrreiches
> Beispiel:
>
> https://lwn.net/Articles/342330/
>
> Bei UB verwandelt sich potentiell dein ganzer Code in eine Bombe.

Mein Code ist das nicht. Und auch der Beispielcode verwandelt sich nicht 
in eine Bombe, sondern schafft einen Zugang u.a für Bombemleger. Ist 
auch nicht schön, aber doch ein feiner Unterschied.

Autor: Jobst Q. (joquis)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Der Andere schrieb:
>> X[n+1]=n;n++;
>
> Diesen Unfug auf Teufel komm raus Zeilen sparen zu wollen haben wir
> zuletzt auf einem Commodore CBM 4008 gemacht. Da war das Problem, daß
> der Basic Source Code sonst wegen der Zeilenumbrüche zu groß wurde um
> ins Ram zu passen.
>
> Ich denke doch daß man in heutiger Zeit mit Terabytes an Plattenplatz
> und Gigabytes an RAM die paar carriage return / Line Feed spendieren
> kann um das Progamm eindeutig und lesbar zu machen.

Die Zeile ist sowohl eindeutig als auch lesbar. Anweisungen werden in C 
mit ';' getrennt. Die grafische Verteilung mit Zeilenumbrüchen 
unterliegt der künstlerischen Freiheit des Programmierers.

RAM und Plattenplatz ist unwesentlich gegenüber dem Platz auf dem 
Bildschirm, den man noch überschauen kann. Wenn er vertikal ausufert ist 
das genauso ein Hindernis für die Lesbarkeit wie ein horizontales 
Ausufern. Davon kann aber bei 13 Zeichen in der Zeile noch nicht die 
Redes sein.

Autor: Dumdi D. (dumdidum)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Jobst Q. schrieb:
> Und auch der Beispielcode verwandelt sich nicht in eine Bombe, sondern
> schafft einen Zugang u.a für Bombemleger. Ist auch nicht schön, aber
> doch ein feiner Unterschied

Das ist eher noch schlimmer, da jemand mit Absichten dann das System 
uebernimmt. Bei Zufall hat man hingegen ja immer eine Chance.

Autor: Heiko L. (zer0)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Le X. schrieb:
> Dass es in der Praxis keine Implementierung eines C-Compilers gibt der
> dir bei einem signed-overflow die Festplatte löscht weißt du genauso gut
> wie ich.

Genügt doch, wenn in dem Fall ein paar CPU-Flags nicht gecleared werden 
und deshalb der nächste Jump ein bisschen daneben geht.
Ein Compiler-Bug wäre das nur aus Kulanz. Ein brauchbarer Compiler ganz 
sicher nicht. Ich kann's auch wiederholen: Der Standard definiert in der 
Hinsicht nur das absolute Minimum dessen, was erforderlich ist, um 
überhaupt ein lauffähiges Programm schreiben zu können.
Wenn eines so sicher ist, wie das Amen in der Kirche, dann dass solche 
ungeprüften int-Additionen in der Praxis durchaus vorkommen. In Java zB 
ist das anders. Da kann man an den aufgerufenen Funktionen sehen, ob da 
potentiell I/O stattfindet.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.