Meinews.de  


Zurück   Meinews.de > Forum > Newsgroups de.comp.os.* Forum > Newsgroup de.comp.os.unix.programming
Registrieren FAQ Benutzerliste Kalender Suchen Heutige Beiträge Alle Foren als gelesen markieren

Newsgroup de.comp.os.unix.programming Programmierung unter Unix.

Antwort
 
Themen-Optionen Ansicht
  #1  
Alt 10-13-2009, 07:12 PM
Martin Freiberg
 
Beiträge: n/a
Standard Anfängerfrage zu einer Fehlermeldung.


Ich bin gerade dabei zur Übung ein Kernelmodul zu schreiben.


Variablen Definition:
short errzaehl = 0;


Im Programm (in einer Funktion):

errzaehl = ++errzaehl & 0x1FFF;

Ergibt beim Kompilieren für diese Zeile die Meldung:

Warnung: Operation auf >errzaehl< könnte undefiniert sein.

Ändere ich das ganze hingegen ab:

++errzaehl;
errzaehl = errzaehl & 0x1FFF;

gibt es keine Warnung. Da ist der gcc zufrieden. Warum?

gcc 3.4.6 (Ubuntu 3.4.6-8ubuntu2) unter Linux.

Danke und Gruß
Martin



Mit Zitat antworten
Alt Today
Advertising
Google Adsense
 
This advertising will not be shown
in this way to registered members.
Register your free account today
and become a member on
Meinews.de
Standard Sponsored Links

  #2  
Alt 10-13-2009, 08:45 PM
Claudio Carobolante
 
Beiträge: n/a
Standard Re: Anfängerfrage zu einer Fehlermeldung.

Martin Freiberg schrieb:

> Ich bin gerade dabei zur Übung ein Kernelmodul zu schreiben.
>
> Variablen Definition:
> short errzaehl = 0;
>
> Im Programm (in einer Funktion):
>
> errzaehl = ++errzaehl & 0x1FFF;
>
> Ergibt beim Kompilieren für diese Zeile die Meldung:
>
> Warnung: Operation auf >errzaehl< könnte undefiniert sein.
>
> Ändere ich das ganze hingegen ab:
>
> ++errzaehl;
> errzaehl = errzaehl & 0x1FFF;
>
> gibt es keine Warnung. Da ist der gcc zufrieden. Warum?
>
> gcc 3.4.6 (Ubuntu 3.4.6-8ubuntu2) unter Linux.


Auf das Objekt 'errzaehl' wir im ersten Beispiel zwischen zwei
Sequenzpunkten mehr als einmal schreibend zugegriffen. Wie sich ein
Programm (der Wert in dem Objekt) dann zu verhalten hat, ist nicht
definiert.

cc
Mit Zitat antworten
  #3  
Alt 10-22-2009, 06:31 PM
Martin Freiberg
 
Beiträge: n/a
Standard Re: Anfängerfrage zu einer Fehlermeldung.

Claudio Carobolante schrieb:
> Martin Freiberg schrieb:



>> errzaehl = ++errzaehl & 0x1FFF;
>> Warnung: Operation auf >errzaehl< könnte undefiniert sein.


>> ++errzaehl;
>> errzaehl = errzaehl & 0x1FFF;
>> gibt es keine Warnung. Da ist der gcc zufrieden. Warum?


> Auf das Objekt 'errzaehl' wir im ersten Beispiel zwischen zwei
> Sequenzpunkten mehr als einmal schreibend zugegriffen. Wie sich ein
> Programm (der Wert in dem Objekt) dann zu verhalten hat, ist nicht
> definiert.


Sorry, aber das kapiere ich jetzt nicht.

Ist Ersteres nicht nur die Kurzform für das zweite Beispiel?

Ich lese es so das so das im ersten Beispiel zuerst der Wert dieser
Variable inkrementiert wird, dann die binäre Und-Verknüpfung erfolgt und
zuletzt das Ergebnis wieder in der Variable landet.

Die Reihenfolge ist doch fest vorgegeben, oder etwa nicht?

Gruß
Martin


Mit Zitat antworten
  #4  
Alt 10-22-2009, 09:54 PM
Thomas Rachel
 
Beiträge: n/a
Standard Re: Anfängerfrage zu einer Fehlermeldung.

Martin Freiberg schrieb:

>>> errzaehl = ++errzaehl & 0x1FFF;
>>> Warnung: Operation auf >errzaehl< könnte undefiniert sein.

>
>>> ++errzaehl;
>>> errzaehl = errzaehl & 0x1FFF;


> Sorry, aber das kapiere ich jetzt nicht.
>
> Ist Ersteres nicht nur die Kurzform für das zweite Beispiel?


Nein.

++errzaehl ist (vom Ergebnis her) die Abkürzung für

(errzaehl = errzaehl + 1).

Also lautet Dein erstes Beispiel

errzaehl = (errzaehl = errzaehl + 1) & 0x1FFF;

Nur - welche der Beiden Zuordnungen gilt nun? Das ist eben undefiniert.

Was Du vermutlich willst, ist

errzaehl = (errzaehl + 1) & 0x1FFF;


> Ich lese es so das so das im ersten Beispiel zuerst der Wert dieser
> Variable inkrementiert wird, dann die binäre Und-Verknüpfung erfolgt und
> zuletzt das Ergebnis wieder in der Variable landet.


Eben. Die Variable wird zweimal beschrieben - ohne Sequenzpunkt
dazwischen. Dies macht die Reihenfolge der Auswertung undefiniert.

Ebenso könnte folgendes passieren:

errzaehl wird inkrementiert, ver&et und dann an errzaehl zugewiesen, und
danach wird der inkrementierte, aber unver&ete Wert in die Variable
geschrieben.

Und außerdem - warum zweimal zuweisen? Eine Zuweisung am Ende sollte
doch ausreichen...


Thomas
Mit Zitat antworten
  #5  
Alt 10-24-2009, 02:21 PM
Martin Freiberg
 
Beiträge: n/a
Standard Re: Anfängerfrage zu einer Fehlermeldung.

Thomas Rachel schrieb:
> Martin Freiberg schrieb:



>>>> errzaehl = ++errzaehl & 0x1FFF;
>>>> Warnung: Operation auf >errzaehl< könnte undefiniert sein.
>>>> ++errzaehl;
>>>> errzaehl = errzaehl & 0x1FFF;


>> Ist Ersteres nicht nur die Kurzform für das zweite Beispiel?

> Nein.
> ++errzaehl ist (vom Ergebnis her) die Abkürzung für
> (errzaehl = errzaehl + 1).
> Also lautet Dein erstes Beispiel
> errzaehl = (errzaehl = errzaehl + 1) & 0x1FFF;


Oha, und ich dachte das ++errzaehl eindeutig ist und klar ein
vorhergehendes increment der Variablen bedeutet.
Zumal doch die Reihenfolge gilt, das Klammern zuerst abgearbeitet werden.

> errzaehl = (errzaehl = errzaehl + 1) & 0x1FFF;


müsste dann nach Klammerregel doch zu

errzaehl = errzaehl + 1;
errzaehl = errzaehl & 0x1FFF;

werden.

Wenn man die Klammern weg lässt bzw. die öffnende verschiebt

errzaehl = errzaehl = (errzaehl + 1) & 0x1FFF;

dann währe die Sache vollends klar.


> Was Du vermutlich willst, ist
>
> errzaehl = (errzaehl + 1) & 0x1FFF;


Lässt sich das korrekt zu

errzaehl = (++errzaehl) & 0x1FFF;

abkürzen, oder sollte man diese Abkürzungen vermeiden und lieber

++errzaehl;
errzaehl &= 0x1FFF;

schreiben?


Danke & Gruß

Martin


Mit Zitat antworten
  #6  
Alt 10-24-2009, 10:56 PM
Juergen Ilse
 
Beiträge: n/a
Standard Re: Anfängerfrage zu einer Fehlermeldung.

Hallo,

Martin Freiberg <lyki_*web.de> wrote:
> Thomas Rachel schrieb:
>> Martin Freiberg schrieb:
>>>>> errzaehl = ++errzaehl & 0x1FFF;
>>>>> Warnung: Operation auf >errzaehl< könnte undefiniert sein.
>>>>> ++errzaehl;
>>>>> errzaehl = errzaehl & 0x1FFF;
>>> Ist Ersteres nicht nur die Kurzform für das zweite Beispiel?

>> Nein.
>> ++errzaehl ist (vom Ergebnis her) die Abkürzung für
>> (errzaehl = errzaehl + 1).
>> Also lautet Dein erstes Beispiel
>> errzaehl = (errzaehl = errzaehl + 1) & 0x1FFF;

> Oha, und ich dachte das ++errzaehl eindeutig ist und klar ein
> vorhergehendes increment der Variablen bedeutet.


Das ist auch so. Allerdings kannst du dich erst ab dem naechsten
"Sequenzpunkt" darauf verlassen, dass die Variable um eins erhoeht
wurde. Die Erhoehung des Variablenwertes kann *irgendwann* vor dem
nachsten Sequenzpunkt erfolgen, also sowohl vor als auch nach der
Wertzuweisung (und wenn der um eins erhoehte urspruengliche Wert
von erzaehl erst *nach* der Zuweisung wieder in der Variable erzaehl
gespeichert wird, ueberschreibt das den neu zugewiesenen Wert von
erzaehl ...). Der Ausdruck erzaehl++ ist durchaus klar und eindeutig,
aber er veraendert den Wert von erzaehl. Und zwischen zwei Seuqenz-
punkten darf der Wert eienr Variablen nur *einmal* veraendert werden,
sonst ist das Ergebnis undefiniert. Ein Sequnezpunkt waere z.B. das
Semikolon am Ende eines Statements (es gibt noch einige Moeglich-
keiten mehr). Der Ausdruck "erzaehl++" hat einen Wert, und zwar den
vorherigen Wert von erzahl um 1 erhoeht. Aber auch wenn der Wert des
Ausdrucks in deinem Beispiel sicher vor der Zuweisung berechnet
werden muss, heisst das nicht, dass die "Nebenwirkung" des Ausdrucks
(Aenderung des Wertes der Variablen erzahl) auch schon vor der Zu-
weisung statfinden muss: der Standard garantiert nur, dass diese
"Nebenwirkung" irgendwann vor dem naechsten Sequenzpunkt vollendet
ist.

> Zumal doch die Reihenfolge gilt, das Klammern zuerst abgearbeitet werden.
> > errzaehl = (errzaehl = errzaehl + 1) & 0x1FFF;


Das spielt fuer die Berechnung der Werte der Ausdruecke eine Rolle, nicht
aber fuer die Reihenfolge der Wertaenderungn der Variablen. Ja, das ist
ein Untrerschied. Die Reihenfolge der "Wertaenderungen der Variablen"
kannst du nicht beeinflussen, solange da kein Sequenzpunkt dazwischen
liegt (bei einem Sequenzpunkt muessen alle Wirkungen eines Ausdrucks
vor diesem Sequenzpunkt vollstaendig abgearbeitet sein).

> müsste dann nach Klammerregel doch zu
>
> errzaehl = errzaehl + 1;
> errzaehl = errzaehl & 0x1FFF;
>
> werden.


Nein, siehe oben. Diese Fassung hat nur dshalb gegenueber der dort oben
stehenden nicht das selbe Problem, weil du durch die Aufteilung auf 2
Statements einen Sequenzpunkt (das Semikolon nach der ersten Zeile)
zwischen den beiden Ausdruecken die den Wert von erzaehl veraendern
eingefuegt hast.

> Wenn man die Klammern weg lässt bzw. die öffnende verschiebt
>
> errzaehl = errzaehl = (errzaehl + 1) & 0x1FFF;
>
> dann währe die Sache vollends klar.


Die Zuweisung ist kein Sequenzpunkt, deswegen waere der Ausdruck noch
immer "undefiniert" (denn du hast in der gesamten Zeile keinen Sequenz-
punkt).

>> Was Du vermutlich willst, ist
>>
>> errzaehl = (errzaehl + 1) & 0x1FFF;

>
> Lässt sich das korrekt zu
>
> errzaehl = (++errzaehl) & 0x1FFF;
>
> abkürzen, oder sollte man diese Abkürzungen vermeiden und lieber


Damit kuerzt du doch gar nichts ab. Abgesehen von den (nicht zwingend
erforderlichen) Leerzeichen sind doch beide Zeilen exakt gleich lang.
Aber selbst wenn deine Fassung nicht "undefiniert" waere, haette sie
nicht die geringsten Vorteile.

> ++errzaehl;
> errzaehl &= 0x1FFF;
>
> schreiben?


Das koennte man, aber warum sollte man das tun? Ist diese Version fuer dich
klarer und schneller erkennbar als

>> errzaehl = (errzaehl + 1) & 0x1FFF;


? Wohl eher nicht, also warum so etwas schreiben? Um den Ruf von C als
"kryptische Sprache" zu festigen?

Tschuess,
Juergen Ilse (juergen*usenet-verwaltung.de)
--
Ein Domainname (auch wenn er Teil einer Mailadresse ist) ist nur ein Name,
nicht mehr und nicht weniger ...
Mit Zitat antworten
  #7  
Alt 10-25-2009, 04:35 PM
Rainer Weikusat
 
Beiträge: n/a
Standard Re: Anfängerfrage zu einer Fehlermeldung.

Juergen Ilse <juergen*usenet-verwaltung.de> writes:
> Martin Freiberg <lyki_*web.de> wrote:


[...]

>> ++errzaehl;
>> errzaehl &= 0x1FFF;
>>
>> schreiben?

>
> Das koennte man, aber warum sollte man das tun? Ist diese Version fuer dich
> klarer und schneller erkennbar als


Fuer mich ist sie das zum Beispiel: Es werden nacheinander zwei
Manipulationen des Wertes von errzaehl vorgenommen, zum einen wird der
Wert inkrementiert, zum anderen der inkrementierte Wert modulo 8192
'heruntergebrochen'. Logisch haben diese beiden Operationen nichts
miteinander zu tun, genausogut koennte in der ersten Zeile in
Dekrement erfolgen oder in der zweiten eine Beschraenkung auf einen
anderen Zahlenbereich.

>>> errzaehl = (errzaehl + 1) & 0x1FFF;

>
> ? Wohl eher nicht, also warum so etwas schreiben? Um den Ruf von C als
> "kryptische Sprache" zu festigen?


Dafuer wuerde ich

errzaehl = errzaehl + 1 & 0x1fff

vorschlagen (ja, die Prioritaeten sind so) :->. Es ist mir allerdings
nicht ganz ersichtlich, warum der zusammengesetzte Ausdruck anstelle
der zwei separaten Operationen aus sich heraus irgendwie
'verstaendlicher' sein sollte: Er dehnt sich in die Breite anstatt in
die Laenge und ich wuerde ihn einen truegerischerweise mathematischer
aussehenden nennen (truegerisch wegen des &).
Mit Zitat antworten
  #8  
Alt 10-25-2009, 06:51 PM
Martin Freiberg
 
Beiträge: n/a
Standard Re: Anfängerfrage zu einer Fehlermeldung.

Juergen Ilse schrieb:
> Martin Freiberg <lyki_*web.de> wrote:


Hallo,

> Das ist auch so. Allerdings kannst du dich erst ab dem naechsten
> "Sequenzpunkt" darauf verlassen, dass die Variable um eins erhoeht
> wurde.


Sprich, der Compiler zerlegt das ganze und sortiert das unter
Umständen um?
Also sollte ich davon ausgehen das wenn ich eine korrekte Reihenfolge
haben will, am besten für jeden Befehl eine eigene Zeile verwende.


> erzaehl ...). Der Ausdruck erzaehl++ ist durchaus klar und eindeutig,
> aber er veraendert den Wert von erzaehl. Und zwischen zwei Seuqenz-
> punkten darf der Wert eienr Variablen nur *einmal* veraendert werden,
> sonst ist das Ergebnis undefiniert. Ein Sequnezpunkt waere z.B. das


Was mich aber noch mehr verwirrt.

Bei

errzaehl = (errzaehl +1) & 0x1FFF;

müsste doch das gleiche Problem auftreten. Denn der Ausdruck innerhalb
der Klammer macht doch auch nichts anderes den Wert der Variable um eins
zu erhöhen. Oder wird liegt hier drin wiederum ein Sequenzpunkt?

Irgend wie bin ich da jetzt ein wenig Begriffsstutzig.


>> errzaehl = (++errzaehl) & 0x1FFF;
>> abkürzen, oder sollte man diese Abkürzungen vermeiden und lieber

>
> Damit kuerzt du doch gar nichts ab. Abgesehen von den (nicht zwingend
> erforderlichen) Leerzeichen sind doch beide Zeilen exakt gleich lang.


Ich habe gelesen das man durch die Leerzeichen Fehler vermeiden kann.


>> ++errzaehl;
>> errzaehl &= 0x1FFF;

>
> Das koennte man, aber warum sollte man das tun? Ist diese Version fuer dich
> klarer und schneller erkennbar als
>
>>> errzaehl = (errzaehl + 1) & 0x1FFF;


Ja. Zumal mir der unterschied zwischen dieser Version und der mit
++errzaehl noch nicht völlig einleuchtet.

Zudem habe ich gelesen das man ++Variable vorziehen sollte, da hier oft
der effizientere Code erstellt wird.
Oder erkennen heutige Compiler das und codieren eine Addition um ein zu
einem Increment-Befehl um?


> ? Wohl eher nicht, also warum so etwas schreiben? Um den Ruf von C als
> "kryptische Sprache" zu festigen?


Es liegt wohl mehr am Schreibstil ob etwas Kryptisch ist oder nicht. :-)


Gruß
Martin

Mit Zitat antworten
  #9  
Alt 10-25-2009, 07:38 PM
Juergen Ilse
 
Beiträge: n/a
Standard Re: Anfängerfrage zu einer Fehlermeldung.

Hallo,

Martin Freiberg <lyki_*web.de> wrote:
>> erzaehl ...). Der Ausdruck erzaehl++ ist durchaus klar und eindeutig,
>> aber er veraendert den Wert von erzaehl. Und zwischen zwei Seuqenz-
>> punkten darf der Wert eienr Variablen nur *einmal* veraendert werden,
>> sonst ist das Ergebnis undefiniert. Ein Sequnezpunkt waere z.B. das

> Was mich aber noch mehr verwirrt.
> Bei
> errzaehl = (errzaehl +1) & 0x1FFF;
> müsste doch das gleiche Problem auftreten.


Nein.

> Denn der Ausdruck innerhalb der Klammer macht doch auch nichts anderes
> den Wert der Variable um eins zu erhöhen.


Nein. Der Ausdruck ergibt den um ein erhoehten Inhalt der Variablen,
*aber* der Variablenwert wird dabei *nicht* veraendert (und genau ist
der Grund, weshalb in *deiner* Fassung der Compiler eine Warnung
schmeisst: da wird namlich der Variablenwert unnoetigerweise veraendert).

> Oder wird liegt hier drin wiederum ein Sequenzpunkt?


Nein, aber der Wert von erzahl wird durch den Ausdruck (errzaehl +1)
*nicht* veraendert.

>>> errzaehl = (++errzaehl) & 0x1FFF;
>>> abkürzen, oder sollte man diese Abkürzungen vermeiden und lieber

>> Damit kuerzt du doch gar nichts ab. Abgesehen von den (nicht zwingend
>> erforderlichen) Leerzeichen sind doch beide Zeilen exakt gleich lang.

> Ich habe gelesen das man durch die Leerzeichen Fehler vermeiden kann.


Das ist zwar richtig, aber wenn du die Laenge zweier Ausdruecke vergleichen
willst, erscheint es mir unpraktisch, dabei unnoetige Lerrzeichen mitzu-
zaehlen ...

>>> ++errzaehl;
>>> errzaehl &= 0x1FFF;

>> Das koennte man, aber warum sollte man das tun? Ist diese Version fuer dich
>> klarer und schneller erkennbar als
>>>> errzaehl = (errzaehl + 1) & 0x1FFF;

> Ja.


OK, das ist GEschmacksache (und kommt vielleicht auch auf den Kontext an).

> Zumal mir der unterschied zwischen dieser Version und der mit
> ++errzaehl noch nicht völlig einleuchtet.
> Zudem habe ich gelesen das man ++Variable vorziehen sollte, da hier oft
> der effizientere Code erstellt wird.


Wenn man den Variablenwert dadurch auch aendern will: vielleicht,
wobei das bei vielen modernen Compilern aber keinen wesentlichen
Unterschied ausmacht (der Optimizer wuerde i.d.R. bei sehr vielen
Compilern aus den folgenden Zeilen:

++erzaehl;
erzaehl++;
erzaehl+=1;
erzaehl=erzaehl+1;

jeweils identischen Code erzeugen.

> Oder erkennen heutige Compiler das und codieren eine Addition um ein zu
> einem Increment-Befehl um?


Sehr viele moderne Compiler ja.

Tschuess,
Juergen Ilse (juergen*usenet-verwaltung.de)
--
Ein Domainname (auch wenn er Teil einer Mailadresse ist) ist nur ein Name,
nicht mehr und nicht weniger ...
Mit Zitat antworten
 
Antwort


Themen-Optionen
Ansicht

Forumregeln
Es ist dir nicht erlaubt, neue Themen zu verfassen
Es ist dir nicht erlaubt, auf Beiträge zu antworten
Es ist dir nicht erlaubt, Anhänge anzufügen
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten

vB Code ist An
Smileys sind An
[IMG] Code ist An
HTML-Code ist Aus


Alle Zeitangaben in WEZ. Es ist jetzt 05:59 AM Uhr.





Powered by: vBulletin Version 3.6.7 (Deutsch)
Copyright ©2000 - 2009, Jelsoft Enterprises Ltd.
Forum SEO by Zoints