pointer=SECTOR11_STARTADRESS+i*(sizeof(int));// Hier die Warnung!
10
DataArrayToBeFilled[i]=*pointer;
11
}
12
}
ich bekommen aber eine Warnung von wegen
warning: assignment makes pointer from integer without a cast [enabled
by default]
aber warum? Ich übergebe dem Pointer eine Zahl, diese ist eine Adresse.
Gut, das weiß jetzt der Kompiler ja nicht, kommt deswegen die Warnung
bzw. wie kann ich sie vermeiden?
Ich nutze die CooIDE auf einem STM32F4
Ingo
Davis schrieb:> Alles weitere teilt dir ein gutes C-Buch mit.
Also im C&R wird sich über das direkte Setzen einer Adresse, also nicht
über den &variable - operator, leider aus geschwiegen.
Ingo
>> Ahh, ja, der Cast zu einer Adresse, danke!
Die Frage ist aber eher, warum SECTOR11_STARTADRESS nicht von vorne
herein bereits eine Adresse ist (ein Pointer), sondern ein stink
normaler Integer. Die Makro-Konstante hat ja in ihrem Namen schon den
Zusatz 'ADRESS' (Adresse schreibt sich im Englischen übrigens mit
Doppel-d), ist aber keine Adresse!
Sowas ist nicht gut. Achte mehr auf Konsistenz zwischen dem was deine
Namen im Programm aussagen, und was sie tatsächlich sind - welche
Datentypen dahinter stecken!
Wird SECTOR11_STARTADRESS immer im Sinne von 'Pointer auf Integer'
benutzt?
Wenn ja, dann
1
#define SECTOR11_STARTADRESS ((int*)0x080C0000)
und dafür im Code
1
for(inti=0;i<SizeOfArray;i++){
2
DataArrayToBeFilled[i]=SECTOR11_STARTADRESS[i];
3
}
Oder ist SECTOR11_STARTADRESS eher als allgemeiner Pointer in den
Speicher anzusehen, an dem Bytes liegen. Wenn ja, dann
Aber auf jeden Fall sollte etwas, was im Namen schon 'ADDRESS' im Sinne
einer Speicheradresse trägt, dann auch tatsächlich erst mal ein Pointer
sein und kein Integer!
Ingo schrieb:> Davis schrieb:>> Alles weitere teilt dir ein gutes C-Buch mit.> Also im C&R wird sich über das direkte Setzen einer Adresse, also nicht> über den &variable - operator, leider aus geschwiegen.
Komisch.
Als ich das letzte mal den K&R gelesen habe, war ein Viertel Buch voll
mit Erklärungen zu Datentypen und Castings.
Datentypen sind nicht dazu da, um den Programmierer zu ärgern.
ein 5 ist nun mal ein Integer und kein Pointer.
Karl Heinz Buchegger schrieb:> Die Frage ist aber eher, warum SECTOR11_STARTADRESS nicht von vorne> herein bereits eine Adresse ist (ein Pointer), sondern ein stink> normaler Integer
Weil ich eine weitere Funktion aus der Lib habe, die als Adresse
tatsächlich einen uint32_t erwartet, keine Adresse.
Wenn ich das so mache wie vorgeschlagen bekomme ich hier die Warnung,
ich würde aber ungern die Lib ändern. ich bleibe dann lieber bei einem
Cast zur Adresse.
Ingo
Ingo schrieb:> Karl Heinz Buchegger schrieb:>> Die Frage ist aber eher, warum SECTOR11_STARTADRESS nicht von vorne>> herein bereits eine Adresse ist (ein Pointer), sondern ein stink>> normaler Integer>> Weil ich eine weitere Funktion aus der Lib habe, die als Adresse> tatsächlich einen uint32_t erwartet, keine Adresse.
Das ist für mich ehrlich gesagt kein Argument.
Denn wenn die Funktion die 4 Bytes als float überhmen würde, dann
würdest du da ja auch keinen Float definieren.
Die Funktion will nur sicher stellen, dass du dir darüber im klaren
bist, dass diese Adresse in Form von 4 Bytes angegeben wird (und nicht
mit 2 Bytes oder mit 8 Bytes). Daher der uint32_t.
Das ändert aber nichts daran, dass in DEINEM Programm, in DEINEM Code,
SECTOR11_STARTADRESS die Funktion eines Pointers hat. Sonst würde es ja
nicht 'xxxADDRESS' heißen.
>> Wenn ich das so mache wie vorgeschlagen bekomme ich hier die Warnung,
natürlich:
denn: ein Pointer ist kein Integer und ein Integer ist kein Pointer.
Datentyppmässig gesehen.
> ich würde aber ungern die Lib ändern.
Sagt ja auch keiner
> ich bleibe dann lieber bei einem> Cast zur Adresse.
Ja. An dieser Stelle, beim Aufruf dieser Funktion musst du casten. Das
ist nicht so ungewöhnlich, dass man an den Schnittstellen nach aussen
seine 'Variablen' zurechtcasten muss. Aber das ist kein Argument, dass
man sein ganzes Programm rund um diese von der Schnittstelle
vorgegebenen Datentypen aufbaut. Zuallererst sind die Innereien DEINES
Codes wichtig und nicht das, was dir eine zugekaufte Lib aufs Auge
drückt.
Karl Heinz Buchegger schrieb:> Ja. An dieser Stelle, beim Aufruf dieser Funktion musst du casten. Das> ist nicht so ungewöhnlich, dass man an den Schnittstellen nach aussen> seine 'Variablen' zurechtcasten muss.
Ok, gut zu wissen. Vielen Dank.
@Würg Jonsch
Fast drauf reingefallen ;)
Ingo
Karl Heinz Buchegger schrieb:> Zuallererst sind die Innereien DEINES> Codes wichtig und nicht das, was dir eine zugekaufte Lib aufs Auge> drückt.
Du hast ja recht, wenn von Address die Rede ist, sollte sich dahinter
auch eine "echte" Adresse verbergen.
Ingo
Und ich finde, das ist doch eigentlich gut zu lesen. Man nehme die
Position des i-ten int im 'Array', welches bei SECTOR11_STARTADDRESS
beginnt (aus technischen Gründen muss diese Adresse zu einem uint32_t
gecastet werden) und an dieser Adresse wird dann der Wert von
DataArrayToBeStored[i] abgelegt. Sieht alles gut aus. Die beiden
'Arrayzugriffe' sind identisch und überzeugt mich insofern, dass das in
Ordnung ist.
Wenn ich dann noch die Sicherheitskarte ausspielen will, dann mach ich
mir eine Zwischenfunktion, die geinlined wird
1
inlinevoidFLASH_ProgrammInt(int*Addr,intValue)
2
{
3
FLASH_ProgramWord((uint32_t)Addr,Value);
4
}
und deren einziger Zweck es ist, mir Typsicherheit zu geben und den
Cast, den mir die Lib aufs Auge drückt an einer Stelle zu kanalisieren.
Im meinem Code benutze ich fortan nur noch FLASH_ProgrammInt um zu
schreiben
Worauf interessanterweise noch gar keiner eingegangen ist, was aber IMHO
immens wichtig ist, das ist der Unterschied zwischen int-Arithmetik
und Pointerarithmetik.
Gehen wir mal aus vom originalen
1
#define SECTOR11_STARTADRESS 0x080C0000
und ferner von einer Plattform mit sizeof(int) != 1
Dann verhalten sich die folgenden 3 Codeschnipsel identisch:
ist hingegen falsch.
http://www.google.com/search?q=pointer-arithmetik
XL
Edit: im ersten Beispiel fehlte eine explizite Klammer. [] bindet
stärker als der Cast, deswegen gehören da Klammern um
(int*)SECTOR11_STARTADRESS
dein Beitrag ist zwar korrekt,
aber wo hat den jemand das untenstehende vorgeschlagen?
Axel Schwenke schrieb:> das bereits vorgeschlagene> int i = 42;> int x = *((int*)SECTOR11_STARTADRESS + i*sizeof(int));>> ist hingegen falsch.
Walter S. schrieb:> dein Beitrag ist zwar korrekt,> aber wo hat den jemand das untenstehende vorgeschlagen?
Hmm. Da habe ich wohl eine Klammer in Dominic (gast) 4. Post übersehen.
Mea culpa!
Bei mir geht eine Warnlampe an, wenn ich Manipulation von Pointern oder
pointerartigen Variablen sehe, die sizeof() beinhalten. Die explizit
verschiedenen Pointertypen wurden ja gerade deswegen eingeführt, damit
man sizeof() nicht mehr braucht.
Das tatsächliche Problem ist die lib-Funktion, die als Adresse im Flash
ein uint_32t sehen will. Ein void* wäre angemessen gewesen.
XL