Dienstag, 7. Januar 2014

Statische Variablen

Gestern abend räsonierte ich noch über rätselhafte Fixsterne. Das Rätsel der zwei verschiedenen Positionen desselben Fixsterns (Aldebaran) war schnell gelöst.

Es ist so, wie ich gestern schon schrieb:

Das kann nur bedeuten, dass es noch irgendeinen anderen, nicht in swed enthaltenen, Zustand im Programm gibt. Das werde ich morgen weiter analysieren.
Und dieser verborgene Zustand bestand aus zwei in swe_fixstar deklarierten statischen Variablen:
  static char slast_stardata[AS_MAXCH];
  static char slast_starname[AS_MAXCH];
die zur Pufferung des zuletzt gelesenen Satzes im Fixsternkatalog verwendet wurden.

Das erklärt, dass der innere Zustand des Programms beim zweiten, identischen Aufruf ein anderer war als beim ersten Aufruf. Nun waren die beiden statischen Variablen - noch vom ersten Aufruf - gefüllt.

Wenn es aber nur eine Pufferung war - warum ergab der zweite Aufruf dann andere Werte als der erste?

Der Grund ist, dass ich durch das Löschen der swed (z.B. mittels eines swe_close()-Aufrufs, oder - wie in meinem Testprogramm: explizit) auch die Information swed.is_old_starfile = TRUE zerstört hatte, die beim ersten Aufruf ermittelt worden war (in meinem Ephemeridenverzeichnis befand sich nämlich nur das "alte" File fixstars.cat - was aber ja nicht verboten ist).

  if (swed.fixfp == NULL) {
    if ((swed.fixfp = swi_fopen(SEI_FILE_FIXSTAR, SE_STARFILE, swed.ephepath, serr)) == NULL) {
      swed.is_old_starfile = TRUE;
      if ((swed.fixfp = swi_fopen(SEI_FILE_FIXSTAR, SE_STARFILE_OLD, swed.ephepath, NULL)) == NULL) {
        ...
Wenn der Eintrag im Puffer gefunden wurde, springt das Programm direkt zum Label found. Nach Erreichen der Sprungmarke gibt es aber noch eine Stelle, in der mit den Koordinaten abhängig vom Flag swed.is_old_starfile unterschiedlich weitergerechnet wird. Das erklärt's:
  /* speed in ra and de, degrees per century */
  if (swed.is_old_starfile == TRUE) {
    ra_pm = ra_pm * 15 / 3600.0;
    de_pm = de_pm / 3600.0;
  } else {
    ra_pm = ra_pm / 10.0 / 3600.0;
    de_pm = de_pm / 10.0 / 3600.0;
    parall /= 1000.0;
  }
Nach Ausbau dieser Pufferung und Entfernung der beiden statischen Variablen slast_stardata und slast_starname liefen die beiden Fixsterntests nun beide mit OK durch. Insbesondere müssen die beiden sukzessiven Aufrufe nun auch dieselben Ergebnisse gebracht haben.

Nachdem dies erledigt war, habe ich auch das neuere File sefstars.txt ins Ephemeridenverzeichnis hinzugefügt. Im Grunde ist fixstars.cat ja ein alter Zopf, den ich irgendwann kappen kann.

Wie ich ja früher auch schon den Compileparameter TRACE eliminiert habe.

Das Tool nm, das das Symbolverzeichnis eines Objektfiles auflistet, zeigt, dass es noch zwei weitere statische Variablen in sweph.c gibt: epheflag_sv und nutflag:

ruediger@herschel:~/workspace/swepar/src$ nm -aC sweph.o | grep ' [bB] ' 
00000000 b .bss
00000204 b epheflag_sv.3938
00000200 b nutflag.5350
00000000 b slast_stardata.5374
00000100 b slast_starname.5375
Um diese werde ich mich morgen kümmern.

Verwirrend kommt nun hinzu, dass der Start des Programms test_calc_reduce in der Bash nicht mehr funktioniert, wohl aber der Start von Eclipse aus mittels Run As -> Local C/C++ Application

Keine Kommentare:

Kommentar veröffentlichen