Forum: Compiler & IDEs Blöde warning


von Nucor (Gast)


Lesenswert?

Hi,

ich schaffe es nicht die Warning
warning: cast to pointer from integer of different size
beim cast auf den Pointer p wegzubekommen.


uint8_t  n;

const uint8_t* p;




n = 123;

p = (uint8_t*) n;  // <-- warning


auch pVar = (const uint8_t*) n erzeugt dieselbe Warning

n und p sind vom selben Typ. n als Variable, p als Pointer.
Eigentlich müsste der cast funktionieren.

Unter WinAVR-20070525 gabs das Problem nicht.
Mit dem neuen WinAVR-20080610 kommt die Warnung.

Was kann ich tun um die Warning los zu werden ?

mfg

Nucor

von Klugscheisser (Gast)


Lesenswert?

>n und p sind vom selben Typ. n als Variable, p als Pointer.
>Eigentlich müsste der cast funktionieren.
Nein, das müsste nicht funktionieren.

Der Typ einer Variablen und ein Zeiger auf diese haben erstmal nichts 
miteinander gemein. Vor allem aber, und das ist hier die Aussage der 
Warning, sind sie nicht zwangswiese gleich gross.

Mir ist auch nicht ganz klar, was Du an "cast to pointer from integer of 
different size" nicht verstehst. Du versuchst ein cast einer 8 bit 
integer variablen auf einen Zeiger, der nun zufällig (naja) nicht auch 8 
bit gross ist. Sehr wahrscheinlich ist er mindestens 16 Bit breit.

Was willst Du denn da erreichen?

Ohne Fehler (und ohne cast) sollte jedenfalls:

p =  &n;

gehen.

von Chris (Gast)


Lesenswert?

Der Compiler möchte dir damit sagen, dass ein Zeiger auf deiner 
Zielplattform mehr als 8 Bits hat. Ein uint8_t ist also schlicht zu 
klein, um einen allgemeinen Zeiger darzustellen.
Du solltest dir also zuerst nochmal sehr gut überlegen, ob es wirklich 
sinnvoll ist einen uint8_t in einen Zeiger zu casten, obwohl es 
unterschiedlich große Typen sind.



Falls es eine C++-Datei sein sollte, könntest du mal probieren, ob die 
Warnung auch mit reinterpret_cast auftaucht.

von Nucor (Gast)


Lesenswert?

Hi,

p =  &n; ist natürlich richtig. Danke.

(uint8_t*) brauche ich um eeprom_read_byte(const uint8_t* p) zu 
versorgen.

Das eigentliche Problem ist, daß in eeprom_read_byte ein
Rücksprung nach Main() erfolgt. Ich hab' den Ablauf mit
einem JTAG - Ice bis in die Routine eeprom_read_byte verfolgt.

Ein Assemblerbefehl ST X, R24 löst einen Sprung nach 0x34 aus, von
wo ein Vektor nach Main zeigt.

Ich bins leid und gehe auf WinAVR-20070525 zurück. Mir fehlt einfach die
Zeit mich mit solchen Bugs zu beschäftigen.

mfg

Nucor

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Nucor wrote:

> Ich bins leid und gehe auf WinAVR-20070525 zurück. Mir fehlt einfach die
> Zeit mich mit solchen Bugs zu beschäftigen.

Klar, die Vogel-Strauß-Methode hat schon immer prima funktioniert...

von Klugscheisser (Gast)


Lesenswert?

Naja, ich glaube auch eher das kein Bug im Compiler sondern einer dieser 
typischen Schmutzeffekte von einem etwas seltsamen Code und/oder 
JTAG-ICE ist. Aber dann wird er vermutlich auf das selbe Problem 
stossen. Der Code schmiert vielleicht an einer anderen Stelle ab, aber 
das wird die einzige Veränderung sein.

von Oliver (Gast)


Lesenswert?

Der gezeigte Code

>n = 123;
>p = (uint8_t*) n;

>(uint8_t*) brauche ich um eeprom_read_byte(const uint8_t* p) zu
>versorgen.

wird mit keiner noch so alten WinVAR-Version funktionieren oder 
funktioniert haben.

Da sitzt der Bug vor dem Computer.

Oliver

von linuxgeek (Gast)


Lesenswert?

> Ich bins leid und gehe auf WinAVR-20070525 zurück. Mir fehlt einfach die
> Zeit mich mit solchen Bugs zu beschäftigen.

Sehe ich auch so. Bei jeder neuen Version muss man damit rechnen, das 
man seine Projekte nicht mehr ohne weiteres kompilieren kann. Naja, 
Gnulinuxkernelemacsgefrickelkram halt...

von Sven P. (Gast)


Lesenswert?

Oliver wrote:
> Der gezeigte Code
>
>>n = 123;
>>p = (uint8_t*) n;
>
>>(uint8_t*) brauche ich um eeprom_read_byte(const uint8_t* p) zu
>>versorgen.
>
> wird mit keiner noch so alten WinVAR-Version funktionieren oder
> funktioniert haben.

Doch, die Zuweisung ist vollkommen legitim, ist halt "Zeigerarithmetik". 
Ob das letztlich das ist, was der Programmierer sich dabei gedacht hat, 
ist allerdings fraglich...

von Andreas K. (a-k)


Lesenswert?

Es wird schon funktionieren - drum ist es ja eine Warnung und keine 
Fehlermeldung. Ich halte es allerdings für sehr nützlich, dass der 
Compiler darin einem Programmierfehler vermutet, denn in mindestens 99% 
der Fälle hat man solchem Code das "&" vergessen.

Wer diese Warnung partout weghaben will, der muss nur dafür sorgen, dass 
der Compiler den Wert als 16bittig ansieht, indem man ihm das explizit 
mitteilt:
  p = (const uint8_t*)(int)n;

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

> > uint8_t  n;
> >
> > const uint8_t* p;
> > n = 123;
> > p = (uint8_t*) n;

> Doch, die Zuweisung ist vollkommen legitim, ist halt "Zeigerarithmetik".

Nein, das wäre sie nur, wenn sizeof (uint8_t) == sizeof (void*).

Das aber ist nicht der Fall.

"Legal" wäre sie, wenn n vom Typ uint16_t wäre.

(Vorausgesetzt, daß sizeof (void*) == 2 ist, was auf 8-Bit-Maschinen wie 
AVR etc. zutrifft).

von Andreas K. (a-k)


Lesenswert?

Rufus t. Firefly wrote:

>> Doch, die Zuweisung ist vollkommen legitim, ist halt "Zeigerarithmetik".
>
> Nein, das wäre sie nur, wenn sizeof (uint8_t) == sizeof (void*).

Bei einem type cast ist in klassischem C89 fast alles zulässig was sich 
irgendwie in Code umsetzen lässt. "To cast" heisst nicht zufällig 
"wegwerfen", und das Ergebnis von ausgiebiger Verwendung derselben taugt 
oft nur noch dazu.

Hier kommt hinzu, dass "n" zwar 8bittig ist, der Ausdruck "n" aber 
arithmetisch als "int" verarbeitet wird, und damit wieder passt.

Wenn es sich beispielsweise um einen Adressraum <= 256 Bytes handelt 
(EEPROM bei kleinem AVR), ist eine 8bittige Adressrechnung im Prinzip 
sogar verständlich.

von vistageek (Gast)


Lesenswert?

Hier wird mal wieder erheblich Zensur betrieben, finde ich nicht gut!

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Wer verteilt Zensuren?

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

In diesem Thread ist kein einziger Beitrag gelöscht worden; wo nimmt 
"vistageek" etwas wahr, was in seinem Weltbild als "Zensur" bezeichnet 
werden muss?

von Andreas K. (a-k)


Lesenswert?

Vielleicht wundert er sich bloss drüber, dass es #938409 (anderer 
Thread) noch nicht erwischt hat.

von Sven P. (Gast)


Lesenswert?

Rufus t. Firefly wrote:
>> > uint8_t  n;
>> >
>> > const uint8_t* p;
>> > n = 123;
>> > p = (uint8_t*) n;
>
>> Doch, die Zuweisung ist vollkommen legitim, ist halt "Zeigerarithmetik".
>
> Nein, das wäre sie nur, wenn sizeof (uint8_t) == sizeof (void*).
>
> Das aber ist nicht der Fall.

Doch, sie ist legitim. Wenn der Programmierer das so will, ist das 
legitim, denn der Compiler nimmt in erster Linie mal an, dass der 
Programmierer weiß, was er will, und sich bewusst ist, das bei der 
Zuweisung Datenschwund entstehen kann.

> "Legal" wäre sie, wenn n vom Typ uint16_t wäre.

Auch nicht ganz korrekt. Über "legal" und nicht "legal" hab ich gerade 
geschrieben. Wenns denn konform sein soll, dann müsste p vom Typ 
intptr_t sein, denn dafür ist der da.

von Oliver (Gast)


Lesenswert?

>p = (uint8_t*) n;

ist unbestritten legitim, wenn aber, wie Nucor selber festgestellt 
hatte,

>p =  &n;

gewollt war, bezweifele ich immer noch, daß das mit einer alten 
Conpilerversion funktioniert haben soll.

Oliver

von Sven P. (Gast)


Lesenswert?

Oliver wrote:
> gewollt war, bezweifele ich immer noch, daß das mit einer alten
> Conpilerversion funktioniert haben soll.
Daran wiederum würde ich nie zweifeln: "es funktioniert" <--> "es lässt 
sich compilieren". =:-D

von Chris (Gast)


Lesenswert?

> Daran wiederum würde ich nie zweifeln:
> "es funktioniert" <--> "es lässt sich compilieren".

Man sagt, in Haskell treffe diese Äquivalenz tatsächlich zu. Ein Stück 
Code, das den Compiler übersteht, wird irgendetwas sinnvolles tun. Man 
muss dann im zweiten Schritt nur noch herausfinden, was genau es denn 
nun macht.

Manchmal schon schade, dass C so viel "Mist" zulässt. Andererseits, 
genau dafür mag ich C auch wieder. ;)

von Sven P. (Gast)


Lesenswert?

Chris wrote:
>> Daran wiederum würde ich nie zweifeln:
>> "es funktioniert" <--> "es lässt sich compilieren".
>
> Man sagt, in Haskell treffe diese Äquivalenz tatsächlich zu.

NEEEEEIIIIIN.... <---> soll ein WIDERSPRUCH sein...

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
Noch kein Account? Hier anmelden.