Ralf schrieb:> Was passiert in dieser Zuweisung ulNewPosition &= (unsigned long)(~1);> und wofür könnte es gut sein in der Funktion?
ein Cast auf unsigned long einer bitweisen negation der 1 wird mit
ulNewPosition verundet und in ulNewPosition gespeichert.
Gerhard O. schrieb im Beitrag #4920606:
> Aber wie gesagt, das funktioniert nur wenn die Inputparameter Global> sind weil diese Funktion nichts zurück geben kann.
Meines Wissens noch nichtmal dann, weil die Neudefinition die globale
Definition innerhalb der Funktion überdeckt.
(unsigned long)(~1);
ist in binärer Schreibweise 11111111111111111111111111111110, also
4294967294 dezimal. Mit
ulNewPosition &= (unsigned long)(~1);
wird also das niedrigste Bit in ulNewPosition gelöscht.
Stefan
So wie die Funktion implementiert ist, macht sie vom Ergebnis her genau
gar nichts.
Es gibt drei sinnvolle Möglichkeiten:
1.) Entweder die Variablen ulNewPosition und ucMotor sind global
deklariert. Dann ergibt es keinen Sinn, sie der Funktion auch noch zu
übergeben.
2.) Oder man übergibt der Funktion die Adressen der Variablen, die
anderswo deklariert sind. Dann brauchen sie nicht global zu sein und man
kann per Derefenzierung auf sie zugreifen.
3.) Oder man übergibt die Variablen an die Funktion, so wie hier, so
dass sie auf dem Stack liegen. Dann sollte die Funktion aber auch etwas
zurückgeben und nicht als void deklariert sein.
Die übergebenen Variablen landen auf dem Stack, werden dann wie auch
immer verändert und dann weggeschmissen. Ein guter Compiler optimiert
die gesamte Funktion einfach weg.
Joe F. schrieb:> Wie Dussel sagt: diese Funktion bewirkt rein gar nichts.
Mit etwas Grips könnte man sich leicht denken, daß er nur die ihm
unverständlichen Zeilen gepostet hat.
Vollständige Funktionen sieht man hier nur sehr selten.
Das Optimum wäre gewesen, die fraglichen Zeilen im Beitrag zu zitieren
und den kompletten, echten Code als Anhang.
Peter D. schrieb:> Joe F. schrieb:>> Wie Dussel sagt: diese Funktion bewirkt rein gar nichts.>> Mit etwas Grips könnte man sich leicht denken, daß er nur die ihm> unverständlichen Zeilen gepostet hat.
Das ändert doch aber nichts daran, dass die Funktion so nicht
funktioniert.
S. S. schrieb:> (unsigned long)(~1);>> ist in binärer Schreibweise 11111111111111111111111111111110, also> 4294967294 dezimal. Mit>
Bist du dir sicher ?
Die Ziffer 1 ist erst einmal ein integer der bitweise negiert wird und
wenn du den auf einen long castest wird er mit mit 0 und nicht mit 1
vorne aufgefüllt.
Hans-Georg L. schrieb:> Die Ziffer 1 ist erst einmal ein integer der bitweise negiert wird und> wenn du den auf einen long castest wird er mit mit 0 und nicht mit 1> vorne aufgefüllt.
"sign expansion", anyone?
Hans-Georg L. schrieb:> Die Ziffer 1 ist erst einmal ein integer der negiert wird und wenn du> den auf einen long castest wird er mit mit 0 und nicht mit 1 vorne> aufgefüllt.
Guter Einwand, so ists richtig:
Hans-Georg L. schrieb:> Die Ziffer 1 ist erst einmal ein integer der negiert wird und wenn du> den auf einen long castest wird er mit mit 0 und nicht mit 1 vorne> aufgefüllt.
Das klingt erstmal logisch, ein Versuch belehrt mich aber eines
besseren:
1
#include<stdio.h>
2
#include<stdint.h>
3
4
intmain()
5
{
6
printf("sizeof(int): %ld\n",sizeof(int));
7
printf("sizeof(long): %ld\n",sizeof(long));
8
9
printf("%x\n",~1);
10
printf("%lx\n",~1L);
11
printf("%lx\n",(unsignedlong)(~1));
12
printf("%lx\n",(unsignedlong)(~1U));
13
return0;
14
}
1
$ cc a.c && ./a.out
2
sizeof(int): 4
3
sizeof(long): 8
4
fffffffe
5
fffffffffffffffe
6
fffffffffffffffe
7
fffffffe
Es liegt an der Sign-Extension, dass "(unsigned long)(~1)" trotzdem
funktioniert. Rufus hatte den richtigen Riecher.
Ich finde es interessant, wie hier so gerne auf Details der
Implementierung herumgeritten wird, wenn das ganze Code-Beispiel an sich
Müll ist und entsorgt gehört. ;-)
Mark B. schrieb:> Ich finde es interessant, wie hier so gerne auf Details der> Implementierung herumgeritten wird, wenn das ganze Code-Beispiel an sich> Müll ist und entsorgt gehört. ;-)
Ich finde es eher interessant, dass Du einen Auszug aus einer Funktion
nicht akzeptierst und darauf herumreitest. Es ging darum, was eine
einzelne Zeile bewirkt und nicht darum, was eine ganze Funktion bewirkt.
Der Korinther bist Du, nicht die anderen.
Mark B. schrieb:> 1.) Entweder die Variablen ulNewPosition und ucMotor sind global> deklariert. Dann ergibt es keinen Sinn, sie der Funktion auch noch zu> übergeben.
Ich habe es gerade mal kurz mit XCode (meines Wissens gcc) getestet
1
#include<iostream>
2
usingstd::cout;
3
usingstd::cin;
4
5
unsignedshortintglobal;
6
7
voidFunktion(unsignedshortintglobal);
8
9
intmain()
10
{
11
unsignedshortintlokal=5;
12
global=3;
13
14
Funktion(lokal);
15
16
cout<<"lokal="<<lokal<<"; global="<<global<<"\n";
17
18
return0;
19
}
20
21
voidFunktion(unsignedshortintglobal)
22
{
23
global=10;
24
}
ergibt als Ausgabe
lokal=5; global=3
Das heißt, wie ich oben schrieb, wird die globale Variable von der
lokalen Deklaration überdeckt.
Hans-Georg L. schrieb:> S. S. schrieb:>> (unsigned long)(~1);>>>> ist in binärer Schreibweise 11111111111111111111111111111110, also>> 4294967294 dezimal. Mit>>> Bist du dir sicher ?>> Die Ziffer 1 ist erst einmal ein integer der bitweise negiert wird und> wenn du den auf einen long castest wird er mit mit 0 und nicht mit 1> vorne aufgefüllt.
C99 § 6.3.1.1:
> 1 When a value with integer type is converted to another integer type> other than _Bool, if the value can be represented by the new type,> it is unchanged.
"1" ist vom Typ "int", also signed, und deshalb auch "~1", also ist "~1"
negativ (-2), also kann dieser Wert in "unsigned long" nicht
repräsentiert werden.
> 2 Otherwise, if the new type is unsigned, the value is converted by> repeatedly adding or subtracting one more than the maximum value> that can be represented in the new type until the value is in the> range of the new type.
Dieses Verfahren impliziert, dass ein kleinerer Typ mit dem
Vorzeichen-Bit aufgefüllt wird, d.h., das Ergebnis ist das selbe wie bei
"(unsigned long)-2".
Frank M. schrieb:> Mark B. schrieb:>> Ich finde es interessant, wie hier so gerne auf Details der>> Implementierung herumgeritten wird, wenn das ganze Code-Beispiel an sich>> Müll ist und entsorgt gehört. ;-)>> Ich finde es eher interessant, dass Du einen Auszug aus einer Funktion> nicht akzeptierst und darauf herumreitest. Es ging darum, was eine> einzelne Zeile bewirkt und nicht darum, was eine ganze Funktion bewirkt.>> Der Korinther bist Du, nicht die anderen.
Man muss schon ziemlich blind sein oder ein völlig unfähiger
Programmier, um den hier gezeigten Code in irgend einer Weise als
sinnvoll zu bezeichnen.
Mark B. schrieb:> Man muss schon ziemlich blind sein oder ein völlig unfähiger> Programmier, um den hier gezeigten Code in irgend einer Weise als> sinnvoll zu bezeichnen.
Es ging nicht um die Sinnigkeit/Unsinnigkeit. Aber wenn Du das so mit
dem "unfähigen Programmierer" so siehst, akzeptiere ich das ;-)
Rufus Τ. F. schrieb:> Hans-Georg L. schrieb:>> Die Ziffer 1 ist erst einmal ein integer der bitweise negiert wird und>> wenn du den auf einen long castest wird er mit mit 0 und nicht mit 1>> vorne aufgefüllt.>> "sign expansion", anyone?
Du hast recht es wird eine negativer integer daraus. Aber solche
Konstruktionen mit Mischmasch aus Artithmetik und Logig sind äusserst
unübersichtlich ... Ein ~1UL hätte es auch getan.
Und wir wissen ja auch nicht was der Verfasser wirklich gewollt hat.
Frank M. schrieb:> Mark B. schrieb:>> Man muss schon ziemlich blind sein oder ein völlig unfähiger>> Programmier, um den hier gezeigten Code in irgend einer Weise als>> sinnvoll zu bezeichnen.>> Es ging nicht um die Sinnigkeit/Unsinnigkeit.
Wer sagt das?
Wenn Du in einem Code Review sitzt und eine völlig unsinnige Funktion
entdeckst, sprichst Du dann über die Details der Implementierung? Oder
sagst Du: "Diese Funktion ergibt so keinen Sinn. Bitte wegschmeißen und
neu schreiben."
Hans-Georg L. schrieb:> Und wir wissen ja auch nicht was der Verfasser wirklich gewollt hat.
Das ist richtig. Wenn es ihm aber nur um die bitweise Negation gegangen
wäre, wäre es freilich intelligent gewesen auch nur diese Codezeile
hinzuschreiben.
Mark B. schrieb:> Wenn Du in einem Code Review sitzt und eine völlig unsinnige Funktion> entdeckst, sprichst Du dann über die Details der Implementierung?
Es war offensichtlich, dass die Funktion nur in Auszügen abgebildet
wurde. Das kann man unter Einsatz des Verstandes leicht erkennen.
Mark B. schrieb:> Das ist richtig. Wenn es ihm aber nur um die bitweise Negation gegangen> wäre, wäre es freilich intelligent gewesen auch nur diese Codezeile> hinzuschreiben.
Er hat den Funktionskopf hingeschrieben, um die Typen der verwendeten
Variablen anzuzeigen. Ohne diese Typdefinitionen wäre eine einzelne
Zeile ziemlich unsinnig, oder?
Frank M. schrieb:> Mark B. schrieb:>> Wenn Du in einem Code Review sitzt und eine völlig unsinnige Funktion>> entdeckst, sprichst Du dann über die Details der Implementierung?>> Es war offensichtlich, dass die Funktion nur in Auszügen abgebildet> wurde.
Woraus schließt Du das? Der Themenersteller macht hierzu keine weiteren
Angaben.
Mark B. schrieb:> Woraus schließt Du das?
Kleinhirn an Großhirn:
"Was soll diese Funktion? Diese ist unsinnig"
Großhirn an Kleinhirn:
"Möglichkeit 1: Der User ist dumm und kann kein C"
"Möglichkeit 2: Der User ist intelligient und reduziert den Code
auf das Wesentliche"
Kleinhirn an Großhirn:
"Dann hätte auch eine einzelne Zeile gereicht"
Großhirn an Kleinhirn:
"Dann wären die Typen der Variablen (long oder int) nicht klar gewesen"
Ich habe mich für die Intelligenz des Users entschieden, Du für die
Dummheit desselben.
Frank M. schrieb:> Mark B. schrieb:>> Woraus schließt Du das?>> Kleinhirn an Großhirn:>> "Was soll diese Funktion? Diese ist unsinnig">> Großhirn an Kleinhirn:>> "Möglichkeit 1: Der User ist dumm und kann kein C"
Er hast selbst gesagt, dass seine C-Kenntnisse eingerostet sind. Und
Dinge wie Bits setzen, Bits löschen und Bits negieren sind jetzt nicht
unbedingt das, was ich als fortgeschrittene Themen in der
C-Programmierung ansehen würde.
Edit:
Um diese Frage hier zu beantworten:
> und wofür könnte es gut sein in der Funktion?
sollte man dann schon die komplette Funktion vorliegen haben. Nicht
anwesende Code-Teile zu raten ist immer schwierig ;-)
Ralf schrieb:> ulNewPosition &= (unsigned long)(~1);
bit0 in ulNewPosition wird gelöscht.
>> ucMotor &= 1;
ucMotor wird auf 1 gesetzt, sofern bit0 in ucMotor 1 ist.
>ucMotor wird auf 1 gesetzt, sofern bit0 in ucMotor 1 ist.
Naja.
Es werden alle Bits von ucMotor auf Null gesetzt. Nur das LSB (unterste
Bit) bleibt auf 1 wenn es vorher schon 1 war.
Frank M. schrieb:> Großhirn an Kleinhirn:>> "Möglichkeit 1: Der User ist dumm und kann kein C"> "Möglichkeit 2: Der User ist intelligient und reduziert den Code> auf das Wesentliche"
"Möglichkeit 3: Der User Ralf (der sich nicht weiter gemeldet hat,)
veralbert alle
Frank M. schrieb:> Mark B. schrieb:>> Wenn Du in einem Code Review sitzt und eine völlig unsinnige Funktion>> entdeckst, sprichst Du dann über die Details der Implementierung?>> Es war offensichtlich, dass die Funktion nur in Auszügen abgebildet> wurde. Das kann man unter Einsatz des Verstandes leicht erkennen.
Die Überschrift heißt "C-Funktion verstehen", und dann wird eine
C-Funktion hingeschrieben, die in ihrer so hingeschriebenen Gesamtheit
keinen Sinn ergibt. Da finde ich nicht so offensichtlich, dass die
Funktion an sich gar keine Relevanz haben soll.
Frank M. schrieb:> Ich habe mich für die Intelligenz des Users entschieden, Du für die> Dummheit desselben.
Intelligent ist, echten Code hinzuschreiben oder wenigstens Änderungen
gegenüber diesem als solche zu markieren. Dann kann man sich viel
Diskussion sparen.