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
>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.
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.
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
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...
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.
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
> 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...
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...
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;
> > 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).
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.
In diesem Thread ist kein einziger Beitrag gelöscht worden; wo nimmt
"vistageek" etwas wahr, was in seinem Weltbild als "Zensur" bezeichnet
werden muss?
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.
>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
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
> 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. ;)
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...