|
c't Projekte - c't-Bot und c't-Sim -
Mailinglisten
[Voriger (Datum)]
[Nächster (Datum)]
[Voriger (Thread)]
[Nächster (Thread)]
[Nach Datum][Nach Thread]
Absender: Timo Sandmann
Datum: Di, 20.05.2008 13:36:55
In-reply-to:
<48C139945BA47F4DB4DE05DF62CD57AA03B4D1CCC0@xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx>
References:
<48C139945BA47F4DB4DE05DF62CD57AA03B4D1CCC0@xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx>
Hallo,
dann versuch ich mal den Rest in meiner Mittagspause zu beantworten:
Am 20.05.2008 um 11:03 schrieb Menzel, Frank IT-OO4:
-in map.c gibt es das define OLD_GET_SET, welches defaultmäßig nicht
gesetzt ist
In dem o.a. Verhalten benötige ich aber get_field und set_field, die
aber nicht in der map.h deklariert sind. Was ist hier der
Beweggrund, dies so zu deklarieren bzw. wie können diese Routinen in
der map.h deklariert werden um darauf zugreifen zu können (mit dem
define als auch ohne) ?
Nein, das ist ein Missverständnis, wenn OLD_GET_SET nicht gesetzt ist,
wird anstatt get_/set_field() die Funktion access_field() verwendet.
Diese bekommt die (Karten!!)-Koordinaten, einen evtl. zu setzenden
Wert und ein Bit, ob gelesen oder geschrieben werden soll. Nach außen
bietet das exakt dieselbe Funktionalität wie get_ oder set_field().
Der Unterschied ist nur, dass man durch einen Vergleich mehr (RW-Bit)
mit nur einer Funktion auskommt und da die Methode get_section() nur
in get_/set_field() aufgerufen wird, hat der Compiler so die
Möglichkeit ein Inlining von get_section() durchzuführen. Erstens wird
der Zugriff damit schneller und zweitens der benötigte Stack-Speicher
reduziert (hängt mit der Registerbelegung bei Funktionsaufrufen
zusammen). Das Zusammenlegen von get_/set_field() ist also eine reine
interne Optimierung, für alle Funktionen, die darauf zugreifen, ändert
sich gar nichts, dafür sorgen die Makros #define get_field(x, y)
access_field(x, y, 0, 0) und #define set_field(x, y, v)
access_field(x, y, v, 1).
Das weder get_/set_field() noch access_field() nach außen zugänglich
sind, liegt daran, dass sie nicht reentrant sind. Und ein Locking pro
Feldzugriff wäre viel zu langsam. Außerdem arbeiten sie nur mit Map-
Koordinaten, die außerhalb von map.c nichts zu suchen haben.
-Weitere Deklarationen fehlender map.c Routinen in map.h:
World_to_map
Umrechnung hängt von Auflösung und Größe der Karte ab, darum nur intern.
Way_free_fields
Hierfür gibt es map_way_free(), das von außen zugänglich ist und auch
den Zugriff synchronisiert.
Update occupied
Wird nur von update_sensor_distance() verwendet, so dass der Compiler
optimieren kann (gleiche Argumentation wie oben).
Diese sind in der map.c als static deklariert. Hier ist mir unklar,
was dies genau bewirkt bzw. wie ich diese mit dem static in der
map.h deklariere (bekomme ich nur ohne static hin).
static bedeutet hier, dass die Funktion nur innerhalb der Datei
bekannt ist, in der sie auch definiert ist. Dadurch bekommt man a)
keine Probleme mit sich überschneidenden Namen und ermöglicht b) dem
Compiler bei Optimierungen die Funktion zu löschen (spart Platz).
Grüße,
Timo
|
|