Hallo. Ich möchte 2 Zeiger vom Typ uint32* miteinander subtrahieren. Das Ergebnis soll vom Typ uint32 sein: uint32 Result; uint32 *p1,*p2; Result = p1 - p2; Kann es sein, das die rechte Zuweisung zu signed int promoted wird? Misra Check sagt mir das ich signed int zu unsigned long zuweise(Misra Rule 10.3). Gruß Christian
Christian schrieb: > Das Ergebnis soll vom Typ uint32 sein: Warum? Für Differenzen von Zeigern gibt es einen eigenen Datentyp: http://www.cplusplus.com/reference/cstddef/ptrdiff_t/ Christian schrieb: > Kann es sein, das die rechte Zuweisung zu signed int promoted wird? Überlege, was passieren würde, wenn die Operation unsigned durchgeführt würde und p2 grösser als p1 wäre. Würde dann folgendes Beispiel wie erwartet funktionieren?
1 | int * p1, * p2, * i; |
2 | i += p1 - p2; |
Man müsste mal genauer wissen, wozu Du das machen willst. Schon im K&R steht, dass Zeiger und integers nicht beliebig ineinander überführt werden können. Auch ist Arithmetik mit Zeigern nicht genauso unbeschränkt möglich, wie mit integers. Differenz ging und geht aber. Vermutlich steht in den neueren C99, C11 etc. dazu auch etwas - vielleicht sogar in gewisser Hinsicht von K&R abweichend. Aber schon im K&R stand was von ptrdiff_t. Das hilft nicht viel weiter, ich weiß. Soll aber heissen: Lies mal bitte nach.
Wer "... miteinander subtrahieren ..." schreibt, der weiß vielleicht nicht einmal selbst was er will. Die Operation ist weder auf der Ebene von Adressen, noch auf der Ebene von Zahlen sinnvoll.
Buchwert schrieb: > Die Operation ist weder auf der Ebene > von Adressen, noch auf der Ebene von Zahlen sinnvoll. doch ist sie. Wird auch sehr oft gebraucht.
1 | int strlen( const char* s ) |
2 | {
|
3 | const char* t = s; |
4 | while ( *t ) { |
5 | t++; |
6 | }
|
7 | return t - s; |
8 | };
|
(klar kann man das auch anders Programmieren)
Wie im Beispiel oben sind p1 und p2 Zeiger auf 2 Speicherbereiche, deren Abstand mich interessiert. Daher die Subtraktion. Was mich interessiert ist,das das Ergebnis der Subtraktion implicit auf int gecastet wurde.
Peter II schrieb: > Buchwert schrieb: >> Die Operation ist weder auf der Ebene >> von Adressen, noch auf der Ebene von Zahlen sinnvoll. > > doch ist sie. Wird auch sehr oft gebraucht. Nicht von mir. > (klar kann man das auch anders Programmieren) Sollte man auch. > Es ist die Operation des TOs gemeint. Er bekommt nicht umsonst einen Rüffel von Misra.
Christian schrieb: > Wie im Beispiel oben sind p1 und p2 Zeiger auf 2 Speicherbereiche, deren > Abstand mich interessiert. Es dürfen nur Zeiger subtrahiert werden, die auf den gleichen Speicherbereich zeigen: > When two pointers are subtracted, both shall point to elements of the > same array object, or one past the last element of the array object; > the result is the difference of the subscripts of the two array elements. http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1570.pdf Das hat auch seinen Guten Grund:
1 | //Annahme: sizeof(int) == 4
|
2 | int * p1 = (int *)10; |
3 | int * p2 = (int *)20; |
4 | ptrdiff_t Result = p2 - p1; // Result ist 2 |
5 | p1++; // p1 ist nun 14 |
6 | Result = p2 - p1; // Result ist 1 |
:
Bearbeitet durch User
be s. schrieb: > Das hat auch seinen Guten Grund: Oder bei segmentierter Adressierung: int *p1 = malloc(N1); int *p2 = malloc(N2); ptrdiff_t delta = p1 - p2; Da kann je nach Laune delta==0 sein, obwohl p1!=p2.
:
Bearbeitet durch User
Christian schrieb: > Was mich interessiert > ist,das das Ergebnis der Subtraktion implicit auf int gecastet wurde. Wie schon geschrieben wurde, ist das Ergebnis zunächst mal vom Typ ptrdiff_t. Dieser ist laut C-Standard ein Synonym für einen implementationsabhängig definierten signed Integer-Typen - also vermutlich in den allermeisten Fällen ein typedef int. Signed deshalb, weil die Differenz ja auch negativ sein kann. Oliver
Yepp. Und hier noch der Auszug aus dem Standard:
1 | When two pointers are subtracted, both shall point to elements of the same array object, |
2 | or one past the last element of the array object; the result is the difference of the |
3 | subscripts of the two array elements. The size of the result is implementation-defined, |
4 | and its type (a signed integer type) is ptrdiff_t defined in the <stddef.h> header. |
5 | If the result is not representable in an object of that type, the behavior is undefined. |
Oliver S. schrieb: > vermutlich in den allermeisten Fällen ein typedef int. Nein, da bei x86-64 die Pointer 64 Bits breit sind, "int" in den beiden verbreiteten Typmodellen aber trotz 64-Bit Maschine nur 32 Bits hat. Da ist dann "long" (Linux) oder "long long" (Windows) nötig.
:
Bearbeitet durch User
:
Bearbeitet durch User
Christian schrieb: > Hallo. > > Ich möchte 2 Zeiger vom Typ uint32* miteinander subtrahieren. Das > Ergebnis soll vom Typ uint32 sein: > > uint32 Result; > uint32 *p1,*p2; > > Result = p1 - p2; > > Kann es sein, das die rechte Zuweisung zu signed int promoted wird? > Misra Check sagt mir das ich signed int zu unsigned long zuweise(Misra > Rule 10.3). Was willst Du erreichen? Wenn Du MISRA-Regeln zu befolgen hast, dann schreibst Du wohl Code für ein Steuergerät oder dergleichen. Ich wüsste beim besten Willen keinen vernünftigen Grund, warum man da Zeiger voneinander subtrahieren sollte.
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.