Hi,
ich hab die letzten Tage ein wenig herumexperimentiert und dabei
folgende Beobachtung gemacht: Wenn ich Variablen umbenenne (nicht
verschiebe!), dann hat das manchmal(!) Einfluss auf ihre
Speicheradresse.
Das stört mich nicht weiter, aber ich hab mich gefragt, wie der Linker
die Variablen überhaupt anordnet.
Es scheint ja nicht alphabetisch zu sein, aber wohl auch nicht in der
Reihenfolge des Auftretens. Vermutlich ist das völlig unspezifiziert und
er darfs machen wie er will?
Ist das bei Code auch so? Ich habe beobachtet, dass der Code, der
"weiter vorne" beim Linkeraufruf kommt, auch zuerst im Binary steht.
Muss das so sein oder ist auch das unspezifiziert? Ich kenn ein paar
Programme die verlassen sich auf sowas.
Also: Wie und warum macht der Linker das so, und MUSS er das auch machen
oder darf sich das in der nächsten Version ändern?
(nur mal so aus Interesse, ich weiß wie man anständig Code+Daten sicher
an eine fest Adresse bekommt!)
Danke!
meckerziege schrieb:> der Linker
Was ist "der Linker"? Warum sollten verschiedene Linker die Variablen
nicht verschieden ablegen? Und wenn du das mit dem Quellcode
vergleichst, haben Compiler und Optimierer auch noch ein Wörtchen mit zu
reden. Registervariablen tauchen z.B. gar nicht im Speicher auf und was
zu Registervariablen wird, hängt von der Optimierung ab.
Und der Name sagt nun ausgesprochen wenig. Wie sagte man mein EMP-Prof.
immer: "Namen sind Schall und Rauch".
> Ich habe beobachtet, dass der Code, der> "weiter vorne" beim Linkeraufruf kommt, auch zuerst im Binary steht.> Muss das so sein oder ist auch das unspezifiziert?
Das wird wohl auf den von dir verwendeten Linker ankommen. Irgendeine
Reihenfolge muss der Linker verwenden und wenn ihm nichts Besseres
"einfällt", i.e. es keine besonderen Gründe gibt, ist es doch
naheliegend, alles der Reihe nach abzulegen - so wie es kommt.
Werner M. schrieb:> Was ist "der Linker"?
Nachdem das Forum hier "GCC" heißt, wirds wohl auch der GCC Linker sein.
Also "ld" um ihn mal zu rufen...
> Warum sollten verschiedene Linker die Variablen> nicht verschieden ablegen?
exakt das war meine Frage. Gibt es dort harte Vorgaben oder nicht?
Werner M. schrieb:> [..] wenn ihm nichts Besseres> "einfällt", i.e. es keine besonderen Gründe gibt, ist es doch> naheliegend, alles der Reihe nach abzulegen - so wie es kommt.
gibt es denn "besondere Gründe"? (Linkerscript mal ausgenommen)
meckerziege schrieb:> Werner M. schrieb:>> Was ist "der Linker"?>> Nachdem das Forum hier "GCC" heißt, wirds wohl auch der GCC Linker sein.> Also "ld" um ihn mal zu rufen...>>> Warum sollten verschiedene Linker die Variablen>> nicht verschieden ablegen?>> exakt das war meine Frage. Gibt es dort harte Vorgaben oder nicht?
Nun, die Elemente eines Arrays müssen natürlich alle hintereinander
liegen, und die Elemente einer Struktur müssen in der Reihenfolge
gespeichert sein, in der sie definiert sind, aber bei von einander
unabhängigen Variablen gibt es keinerlei Vorgaben zum Speicherort.
meckerziege schrieb:> Werner M. schrieb:>> [..] wenn ihm nichts Besseres>> "einfällt", i.e. es keine besonderen Gründe gibt, ist es doch>> naheliegend, alles der Reihe nach abzulegen - so wie es kommt.>> gibt es denn "besondere Gründe"? (Linkerscript mal ausgenommen)
Globale Variablen, die (implizit oder explizit) mit 0 initialisiert
werden, kommen in der Regel in einen eigenen Bereich. Je nach
Zielplattform können als const definierte Variablen z.B. im Flash
stehen, die anderen im RAM. Außerdem kann der Compiler Variablen auch
z.B. so umsortieren, daß möglichst wenig "Verschnitt" durch die
Alignment-Anforderungen entsteht oder so, daß möglichst viele davon in
einem besonders schnell zugreifbaren Speicher stehen. Da kann es viele
Gründe geben, die aber größtenteils dann von der Zielplattform abhängen.
Rolf Magnus schrieb:> können als const definierte Variablen z.B. im Flash> stehen
Es mag eine Entscheidung des Programmierers sein, const definierte
Variablen ins Flash zu packen, ein Compiler sollte das von sich aus aber
bleiben lassen.
"const" heißt nicht "Konstante". Es heißt nur "_ich_ schreib' nicht
drauf" - "readonly" wäre als Qualifier zweifellos besser gewesen.
Wer "const" mit "konstant" gleichsetzt, kommt spätestens bei "const
volatile" ins Schwimmen ;).
Markus F. schrieb:> Rolf Magnus schrieb:>> können als const definierte Variablen z.B. im Flash>> stehen>> Es mag eine Entscheidung des Programmierers sein, const definierte> Variablen ins Flash zu packen, ein Compiler sollte das von sich aus aber> bleiben lassen.
Ich sehe nichts, was dagegen spricht.
> "const" heißt nicht "Konstante". Es heißt nur "_ich_ schreib' nicht> drauf" - "readonly" wäre als Qualifier zweifellos besser gewesen.
Ja, eben. Mit const gibst du dem Compiler das Versprechen, daß du den
Wert nicht ändern wirst. Der Compiler darf dieses Versprechen für seine
Optimierung nutzen. Wenn du trotzdem versuchst, den Wert zu ändern, ist
dein Programm fehlerhaft, das Verhalten ist undefiniert. Warum sollte
der Compiler die Variable also nicht in den Flash-Speicher stecken
dürfen?
> Wer "const" mit "konstant" gleichsetzt, kommt spätestens bei "const> volatile" ins Schwimmen ;).
Auch da spricht nichts dagegen, die Variable im Flash zu halten.
Übrigens: Auf meinem Linux-PC wird folgendes Programm mit einem
Segmentation Fault terminiert:
1
#include<stdio.h>
2
3
constinti=5;
4
5
intmain()
6
{
7
*(int*)&i=7;
8
printf("%d\n",i);
9
return0;
10
}
1
Program received signal SIGSEGV, Segmentation fault.
2
0x000000000040053f in main () at const.c:7
3
7 *(int*)&i = 7;
Ohne den Cast bekomme ich es nicht einmal durch den Compiler.
Da sagt er dann:
1
const.c: In function ‘main’:
2
const.c:7:7: error: assignment of read-only variable ‘i’
Markus F. schrieb:> Also lieber nicht in's Flash mit der Variable, es könnte ja jemand> anderes drauf schreiben ;).
... wenn sie eben volatile ist. Das hat dann aber mit dem const erstmal
nichts zu tun.