C Pointer Arithmetik - Integer Promotion

Gast #4332844
Lesenswert?

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
#4332859
Lesenswert?

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;
Gast #4332872
Lesenswert?

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.
Gast #4332882
Lesenswert?

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)
Gast #4332890
Lesenswert?

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.
#4332911
Lesenswert?

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
#4332936
Lesenswert?

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
#4332942
Lesenswert?

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.
#4333302
Lesenswert?

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.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren