Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

TagItems und C-Compiler

3 views
Skip to first unread message

Andreas M. Kirchwitz

unread,
Jun 21, 1992, 4:40:05 PM6/21/92
to
Hallo,

als eifriger Amiga-Freak benutze ich in meinen Programmen TagItems.
Nun moechte ich gern, dass der Compiler selbst die Groesse des Tag-
Arrays bestimmt und die einzelnen Elemente der TagItem-Strukturen
selbst mit dem belegt, was ich ihm angebe. In etwa so:


void meine_kleine_prozedur(void) {
{
ULONG tags[] = {RT_WaitPointer,TRUE,TAG_END};
if (rtGetStringA(str,len,title,NULL,(struct TagItem *)tags))

[...]
}


Der Compiler (SAS/C) findet das toll. Der Linker meint dazu jedoch:

Warning! Absolute reference to UNKNOWN
module: rtsup.c file: rtsup.o

("rtsup.c" heisst das Source-File, welches das besagte Code-Fragment enthaelt)
Falls das irgendwie von Interesse ist, die Optionen fuer meinen
Compiler sind: -ma -O -v -cf -cu -cc -ci -ck -cm -ct -tr -mt -Lc -Ld -Ln
(das Programm wird resident gelinkt)

Ich gebe offen zu, dass ich von diesem ganzen Speicherverwaltungskram des
Compilers kaum Ahnung habe. Wenn ich die "ULONG tags..." Zeile z.B. nicht
innerhalb einer Prozedur habe, sondern quasi auf der Hauptebene des Source-
Files, kommt besagte Warning des Linkers nicht -- hat vielleicht was damit
zu tun, dass das eine auf den Stack, das andere in den "normalen" Speicher
kommt. Na, wie auch immer... ich will eigentlich nur (halbwegs verstaend-
lich ;-) wissen, WARUM der Linker meckert und WIE man es richtig macht, so
dass der Linker sich nicht mehr beschwert.


Ich wuerde mich SEHR ueber Hilfe freuen!... Andreas


PS: Ja, richtig... wer ein gutes Gedaechtnis hat, wird feststellen, dass ich
das Problem schon mal hatte: damals hab ich es "geloest", indem ich alle
TagItem-Arrays selbst dimensioniert und jedes einzelne Element per Hand
ausgefuellt habe -- natuerlich geht das so auch, aber es macht SEHR VIEL
Arbeit. (sigh)

--
Andreas M. Kirchwitz, Seesener Str. 69, W-1000 Berlin 31, FRG, +49 30 873376
/ `__' To: amk@{zikzak.in|cs.tu|methan.chemie.fu}-berlin.de
/___(oo)_________ Trust me. I know what I'm doing. ___________ IRC-Nick: `bonzo'
" "

Markus Wild

unread,
Jun 22, 1992, 11:28:43 AM6/22/92
to
In article <5pcer*F...@zikzak.in-berlin.de> a...@zikzak.in-berlin.de (Andreas M. Kirchwitz) writes:
> void meine_kleine_prozedur(void) {
> {
> ULONG tags[] = {RT_WaitPointer,TRUE,TAG_END};
> if (rtGetStringA(str,len,title,NULL,(struct TagItem *)tags))

Naja, schoener (ok, ok, ne Macke von mir ;-)) waere natuerlich:
ULONG tags[] = { { RT_WaitPointer,TRUE, },
{ TAG_END } };

>Der Compiler (SAS/C) findet das toll. Der Linker meint dazu jedoch:

Aha... mein Lieblingsopfer.. mantsch.. BLink hass ;-)))))

> Warning! Absolute reference to UNKNOWN
> module: rtsup.c file: rtsup.o
>

>Ich gebe offen zu, dass ich von diesem ganzen Speicherverwaltungskram des
>Compilers kaum Ahnung habe. Wenn ich die "ULONG tags..." Zeile z.B. nicht
>innerhalb einer Prozedur habe, sondern quasi auf der Hauptebene des Source-
>Files, kommt besagte Warning des Linkers nicht -- hat vielleicht was damit
>zu tun, dass das eine auf den Stack, das andere in den "normalen" Speicher
>kommt. Na, wie auch immer... ich will eigentlich nur (halbwegs verstaend-
>lich ;-) wissen, WARUM der Linker meckert und WIE man es richtig macht, so
>dass der Linker sich nicht mehr beschwert.

Das ganze laeuft unter `automatic aggregate initialisation', und ist
ne ANSI Erweiterung. Mit K&R C darfst Du grundsaetzlich nur nicht-auto
Variablen so initialisieren, zudem muessen die Initializer konstant
sein. Unter ANSI-C duerfen neu auch Stack-Variablen so initialisiert
werden, und der C-Compiler muss dann explizit Code generieren, damit
die Variablen initialisiert werden, jedesmal wenn der Block aktiviert
wird. Nu.. ich schliesse daraus, dass SAS C das entweder nicht kann
(dann duerfte es sich aber nicht ANSI-C schimpfen), oder das ganze nur
buggy implementiert hat. Ein anderes Kapitel ist es allerdings, wenn
Du nicht-konstante Initializers verwendest (also zum Beispiel ein Tag,
der als Argument ne Adresse eines Objekts will). Ich bin mir nicht
sicher, ob das unter ANSI-C vorgesehen ist, oder ob's ne GNU Extension
ist. GCC kann jedenfalls beides.

Wenn das SAS offensichtlich nicht oder nur falsch kann, dann faellt mir
eigentlich nur die folgende Loesung ein (ohne Gewaehr, ist kurz
hingeschrieben...):

struct TagItem *
stuff_tags (ULONG tag, ...)
{
ULONG *tp, *rtp;

/* tags zaehlen (wehe das TAG_END wurde vergessen...) */
for (tp = &tag; *tp != TAG_END; tp += 2) ;
/* das Ende mit kopieren */
tp += 2;
rtp = (ULONG*) malloc (sizeof (ULONG) * (tp - &tag));
/* und kopieren */
for (rtp += tp - &tag; tp >= &tag; )
*rtp-- = *tp--;
return (struct TagItem *) ++rtp;
}

und dann....
struct TagItem *ti = stuff_tags (RT_WaitPointer,TRUE,TAG_END,0);
/* Funktion, die die Tags will, aufrufen */
foo_tags (ti);
free (ti);

> Ich wuerde mich SEHR ueber Hilfe freuen!... Andreas

So einen Hilferuf kann man doch nicht ueberhoeren ;-)

> TagItem-Arrays selbst dimensioniert und jedes einzelne Element per Hand
> ausgefuellt habe -- natuerlich geht das so auch, aber es macht SEHR VIEL
> Arbeit. (sigh)

Aber aber... wir sind doch hier nicht in Modula ;-))

-Markus
--
Markus M. Wild - wi...@nessie.cs.id.ethz.ch | wi...@amiga.physik.unizh.ch
Vital papers will demonstrate their vitality by spontaneously moving
from where you left them to where you can't find them.

Michael Boehnisch

unread,
Jun 23, 1992, 5:26:32 AM6/23/92
to
a...@zikzak.in-berlin.de (Andreas M. Kirchwitz) writes:
:[line eater was here]
:
: void meine_kleine_prozedur(void) {

: {
: ULONG tags[] = {RT_WaitPointer,TRUE,TAG_END};
: if (rtGetStringA(str,len,title,NULL,(struct TagItem *)tags))
:
: [...]
: }
:
:
: Der Compiler (SAS/C) findet das toll. Der Linker meint dazu jedoch:

Das entsetzt mich. Nicht Dein Quellcode, sondern dass der Compiler
nicht meckert... Damit Du weinger Probleme mit meinem Erklaeungs-
versuch hast, erst mal ein paar Begriffsbestimmungen (ja, wie in
der Vorlesung :-)

* Speicherklasse: C laesst als "Modifizierer" fuer Datentypen Angaben
ueber die Verwaltung von Variablen zu. Als da waeren:

- extern : Speicherplatz fuer die Variable/Funktion wird nicht hier,
sondern in einem anderen Modul zur Verfuegung gestellt.

- auto : Zulaessig nur fuer Variablendeklarationen innerhalb von
Funktionen (ist da auch Voreinstellung). Speicherplatz wird zur
Laufzeit des Programms auf dem Prozessor-Stack reserviert.
Dies geschieht "automatisch" beim Betreten des fraglichen Blocks.

Die Lebensdauer von Variablen dieser Speicherklasse reicht nur bis
zum Verlassen des Blocks, danach sind sie "weg".

- static : Hier gibt's zwei Bedeutungen, je nachdem wo die Deklaration
steht (seufz)

= ausserhalb einer Funktion : Das deklarierte Objekt ist nur inner-
halb des aktuellen Moduls bekannt. Das erlaubt die mehrfache Ver-
wendung von Namen in verschiedenen Modulen.

= innerhalb einer Funktion : Das deklarierte Objekt wird nicht zur
Laufzeit, sondern bereits zur Compilationszeit "statisch" erzeugt.
Das erlaubt dem Compiler, diese Variablen vorzubesetzen, und ver-
laengert die Lebensdauer der Variable ueber das Verlassen der
Funktion hinaus. Das Objekt ist aber nur innerhalb des Blocks
bekannt, indem es deklariert wurde.

- register : Das Compiler versucht das Objekt wird in Registern des
Prozessors unterzubringen, sofern moeglich. Beachte, dass Register
keine Addresse haben. Programmstuecke wie:

:
register int x;
:
scanf("%d", &x);
:

zeigen ein voellig undefiniertes Verhalten.

Zurueck zu Deinem Problem - Wenn ich's recht in Erinnerung habe, geht
es so:

Initialisierung in der Deklaration von Variablen am Beginn eines
Blocks ist moeglich fuer:

- "einfache" Variablen (also int, char, float, double...)

- Variablen "komplexer" Datentypen (arrays, structs, ...) NUR in
der Speicherklasse "static".

"static" muss explizit angegeben werden, default ist "auto". Schreibe also

:
static ULONG tags[]....
:

und Dein Code sollte korrekt uebersetzt und gelinkt werden. Die
Initialisierung erfolgt zur Compilationszeit und wird bei erneutem
Aufruf von "meine_kleine_prozedur()" nicht nochmal durchgefuehrt!

Statt dessen hast du in tags[] immer noch die Werte stehen, die beim
letzten Verlassen der Prozedur drin waren.

: Warning! Absolute reference to UNKNOWN
: module: rtsup.c file: rtsup.o
:

Klar. Der Linker suchte ein Objekt zum initialisieren, dessen Speicher-
platz noch gar nicht bekannt sein kann. Aber warum erst der Linker das
bemerkt? Warten wir auf SAS/C 6.0 :-(

So, das war lang. Ich hoffe, ich konnte etwas Licht ins Dunkel
bringen...

Kalahari,
Michael Boehnisch,
bi...@uni-paderborn.de

--

_________________________________________________________
*** Michael Boehnisch ***
*** bi...@uni-paderborn.de I disclaim everything. ***

Markus Wild

unread,
Jun 24, 1992, 11:57:23 AM6/24/92
to
In article <1992Jun23....@uni-paderborn.de> bi...@uni-paderborn.de (Michael Boehnisch) writes:
>Initialisierung in der Deklaration von Variablen am Beginn eines
>Blocks ist moeglich fuer:
>
> - "einfache" Variablen (also int, char, float, double...)
>
> - Variablen "komplexer" Datentypen (arrays, structs, ...) NUR in
> der Speicherklasse "static".

Aeh... das war mal in K&R Zeiten. Wenn ich nicht irre behauptet SAS doch,
ein ANSI-C Compiler zu sein, oder? In diesem Fall muss es auch Arrays
initialisieren koennen (zum Beispiel auch Strings).

> static ULONG tags[]....
> :
>
>und Dein Code sollte korrekt uebersetzt und gelinkt werden. Die

Aeh, das war ja wohl aber nicht was er wollte, denn dann werden die Tags
nur einmal initialisiert, und nicht jedesmal mit den aktuellen Werten...

>bemerkt? Warten wir auf SAS/C 6.0 :-(

Wie gesagt, gcc macht das korrekt, und ist erst noch gratis ;-)

Olaf Barthel

unread,
Jun 22, 1992, 12:14:47 PM6/22/92
to
In article <5pcer*F...@zikzak.in-berlin.de> a...@zikzak.in-berlin.de (Andreas M. Kirchwitz) writes:
> void meine_kleine_prozedur(void) {
> {
> ULONG tags[] = {RT_WaitPointer,TRUE,TAG_END};
> if (rtGetStringA(str,len,title,NULL,(struct TagItem *)tags))
>
> [...]
> }
>
>Der Compiler (SAS/C) findet das toll. Der Linker meint dazu jedoch:
>
> Warning! Absolute reference to UNKNOWN
> module: rtsup.c file: rtsup.o
>
>("rtsup.c" heisst das Source-File, welches das besagte Code-Fragment enthaelt)
>Falls das irgendwie von Interesse ist, die Optionen fuer meinen
>Compiler sind: -ma -O -v -cf -cu -cc -ci -ck -cm -ct -tr -mt -Lc -Ld -Ln
>(das Programm wird resident gelinkt)

Das Problem ist nicht das Tag-Array (warum so kompliziert? ueber den
Stack, siehe z.B. `term', geht es gerade in `C' viel einfacher), sondern wie
ich vermute, die amiga.lib, die Du zum Linken verwendest. Sie enthaelt absolute
(= nicht über A4 zu adressierende) Bezuege auf die Library-Bases. Da fuer ein
resident zu installierendes Programme alle Bezuege auf statische Daten ueber das
Datenbasisregister A4 erfolgen muessen, warnt Dich der Linker an dieser Stelle,
dass etwas nicht in Ordnung ist. Entweder darfst Du jetzt die amiga.lib nicht mehr
mitlinken und musst die pragmas/#?.h Includedateien verwenden, oder Du strickst
die amiga.lib mit Hilfe von Matt Dillon's `libtos' Programm auf A4-relative
Referencen um. Ich habe letztere Methode verwendet, um die amiga.lib mit `term'
zu verwenden. Zwar ist `term' nicht resident einzubinden, aber im Vergleich mit
der amiga.lib mit absoluten Referenzen wird das Programm kuerzer und die
Anzahl der Reloc32-Referenzen im Programm sinkt drastisch.

> Andreas M. Kirchwitz, Seesener Str. 69, W-1000 Berlin 31, FRG, +49 30 873376
> / `__' To: amk@{zikzak.in|cs.tu|methan.chemie.fu}-berlin.de
>/___(oo)_________ Trust me. I know what I'm doing. ___________ IRC-Nick: `bonzo'
> " "

--
Olaf Barthel | UUCP: ol...@sourcery.mxm.sub.org
Brabeckstrasse 35 | cbmvax.commodore.com!cbmehq!sourcery!olsen
D-3000 Hannover 71 | o.ba...@a-link-h.comlink.de
MXM, ECG127 | Z-Net: O.BARTHEL@A-LINK-H
----------------------------------------------------------------------
"Dull, irritating Enchanter (M) seeks exciting, loving F for magic
moments and possible lasting relationship. Must be truthful and
kind or a good liar. No pros or adventurers need reply. Box Y3"

Andreas M. Kirchwitz

unread,
Jun 24, 1992, 4:21:40 PM6/24/92
to
In article <1992Jun24....@bernina.ethz.ch>, Markus Wild writes:

> In article <1992Jun23....@uni-paderborn.de> bi...@uni-paderborn.de (Michael Boehnisch) writes:
> >
> > - Variablen "komplexer" Datentypen (arrays, structs, ...) NUR in
> > der Speicherklasse "static".
>
> Aeh... das war mal in K&R Zeiten. Wenn ich nicht irre behauptet SAS doch,
> ein ANSI-C Compiler zu sein, oder?

so im grossen und ganzen ;-)

> In diesem Fall muss es auch Arrays
> initialisieren koennen (zum Beispiel auch Strings).

Bei Strings kommt -- wie koennte es anders sein -- dieselbe Warning
("Warning! Absolute reference to UNKNOWN") vom Linker.

Von daher erstaunt es mich schon, dass SAS/C das nicht so recht auf die
Reihe kriegt (sagen wir besser: es mit einer Warning quittiert).
Vielleicht eine spezielle Option, die ich bislang uebersehen habe?

Hier benutzen doch sicherlich noch andere Leute SAS/C. Ich kann mir kaum
vorstellen, dass von denen nicht mindestens einer dasselbe Problem hatte und
nun eine Loesung parat hat...

Um Missverstaendnissen vorzubeugen: diese Warning kommt nur, wenn man das
Programm resident linken moechte (also mit "cres.o"), was heutzutage aber
schon fast eine Selbstverstaendlichkeit sein duerfte.

> Aeh, das war ja wohl aber nicht was er wollte, denn dann werden die Tags
> nur einmal initialisiert, und nicht jedesmal mit den aktuellen Werten...

Ja, in der Tat. Die Tags sollen natuerlich stets mit den aktuellen
Werten initialisert werden...

> Wie gesagt, gcc macht das korrekt, und ist erst noch gratis ;-)

^^^^^^^^^
Bald nicht mehr?

Noch auf die Loesung des Probs hoffend... Andreas

Andreas M. Kirchwitz

unread,
Jun 25, 1992, 5:24:50 AM6/25/92
to
In article <olsen...@sourcery.mxm.sub.org>, Olaf Barthel writes:

> >Der Compiler (SAS/C) findet das toll. Der Linker meint dazu jedoch:
> >
> > Warning! Absolute reference to UNKNOWN
> > module: rtsup.c file: rtsup.o
>

> Das Problem ist nicht das Tag-Array (warum so kompliziert? ueber den
> Stack, siehe z.B. `term', geht es gerade in `C' viel einfacher),

Du meinst, die entsprechenden Funktionen direkt mit den Tags aufrufen?
Nun, genau das wollte ich eigentlich vermeiden, um nicht bei der Ver-
wendung von anderen Libraries (z.B. reqtools) unzaehlige *.lib Files
dazulinken zu muessen ;-)

> sondern wie ich vermute, die amiga.lib, die Du zum Linken verwendest.

Die "amiga.lib" linke ich zumindest nicht explizit dazu. Meine Link-Zeile
sieht so aus:

blink FROM LIB:cres.o $(OBJS) TO $(DEST) LIB LIB:lc.lib LIB:reqtools.lib SD SC ND
^^^^^^^^^^ ^^^^^^^^^^^^^^^^
resident das will ich wegkriegen

Und LIB:cres.o vertraegt sich nicht mit der Initialisierung von Tag-Arrays,
Strings etc. innerhalb von Funktionen/Prozeduren. Also selbst wenn man das
Prob mit den Tags umgehen kann (wie z.B. in `term'), wie initialisiere ich
dann Strings, bleibt die Frage? ;-)

Hau? ... Andreas

--

Markus Wild

unread,
Jun 25, 1992, 12:11:33 PM6/25/92
to
In article <Qpbfr*C...@zikzak.in-berlin.de> a...@zikzak.in-berlin.de (Andreas M. Kirchwitz) writes:
>> Wie gesagt, gcc macht das korrekt, und ist erst noch gratis ;-)
> ^^^^^^^^^
>Bald nicht mehr?

Doch doch.. war wohl ne leicht (Schweizer) Dialekt angehauchte
Formulierung, `zudem noch' waere vermutlich klarer gewesen ;-))

Gerald Malitz

unread,
Jun 25, 1992, 3:38:40 PM6/25/92
to
In article <1992Jun23....@uni-paderborn.de>, Michael Boehnisch writes:

> Zurueck zu Deinem Problem - Wenn ich's recht in Erinnerung habe, geht
> es so:
>
> Initialisierung in der Deklaration von Variablen am Beginn eines
> Blocks ist moeglich fuer:
>
> - "einfache" Variablen (also int, char, float, double...)
>
> - Variablen "komplexer" Datentypen (arrays, structs, ...) NUR in
> der Speicherklasse "static".

Nein, wenn ich mich recht erinnere, geht das in ANSI-C auch
mit auto-Variablen. Und wie ich schon geschrieben habe (hier oder
im Reply an Andreas): der Compiler generiert korrekten Code dafuer!

> : Warning! Absolute reference to UNKNOWN
> : module: rtsup.c file: rtsup.o
> :
>
> Klar. Der Linker suchte ein Objekt zum initialisieren, dessen Speicher-
> platz noch gar nicht bekannt sein kann.

Falsch. Der Speicherplatz ist bekannt. Irgendwo zwischen
den anderen initialisierten Variablen. Aber dieser Platz hat keinen
Namen, er ist legal vom C-Code aus auch nicht adressierbar. Der Compiler
generiert fuer die Zeile

ULONG tags[] = { 5, NULL, TAG_END };

Assemblercode, der eben diese namenlosen Adressbereich in einen
Bereich kopiert, der auf dem Stack reserviert wurde und unter
dem Namen tags anzusprechen ist.

> Aber warum erst der Linker das
> bemerkt? Warten wir auf SAS/C 6.0 :-(

Das kann nicht schaden :^)

> So, das war lang. Ich hoffe, ich konnte etwas Licht ins Dunkel
> bringen...

Ich fuerchte, nein. Wie geschrieben, der Compiler ist
unschuldig. Du kannst ja mal das .lnk-File edieren, dort cres.o
durch c.o ersetzen und `blink with dein.lnk' eingeben :) Ich
glaube, die Meldungen des Linkers kann Andreas getrost ignorieren.
Ich jedenfalls mach mir wegen der Option -O mehr sorgen ;)

> Kalahari,
> Michael Boehnisch,
> bi...@uni-paderborn.de

Tschuess, Gerald.

--
// Gerald Malitz, Bolchentwete 4, 3300 Braunschweig, Voice: +49 531 796832
\X/ g...@germal.bs.open.de "Allein der K|ndigungsschutz f|r Schwangere hat den
ungeborenen Kindern tausendfach mehr geholfen als alle Kardindle, Staatsanwdlte
und Richter zusammengenomen" Heiner Gei_ler

Gerald Malitz

unread,
Jun 25, 1992, 4:42:31 AM6/25/92
to
In article <1992Jun22.1...@bernina.ethz.ch>, Markus Wild writes:

> In article <5pcer*F...@zikzak.in-berlin.de> a...@zikzak.in-berlin.de (Andreas M. Kirchwitz) writes:
> > void meine_kleine_prozedur(void) {
> > {
> > ULONG tags[] = {RT_WaitPointer,TRUE,TAG_END};
> > if (rtGetStringA(str,len,title,NULL,(struct TagItem *)tags))
>
> Naja, schoener (ok, ok, ne Macke von mir ;-)) waere natuerlich:
> ULONG tags[] = { { RT_WaitPointer,TRUE, },
> { TAG_END } };

Ich nehme an, Du meinst

struct Tagitem tags[] = { { RT_WaitPointer,TRUE },
{ TAG_END } };

> Das ganze laeuft unter `automatic aggregate initialisation', und ist
> ne ANSI Erweiterung. Mit K&R C darfst Du grundsaetzlich nur nicht-auto
> Variablen so initialisieren, zudem muessen die Initializer konstant
> sein. Unter ANSI-C duerfen neu auch Stack-Variablen so initialisiert
> werden, und der C-Compiler muss dann explizit Code generieren, damit
> die Variablen initialisiert werden, jedesmal wenn der Block aktiviert
> wird. Nu.. ich schliesse daraus, dass SAS C das entweder nicht kann
> (dann duerfte es sich aber nicht ANSI-C schimpfen), oder das ganze nur
> buggy implementiert hat.

Der Compiler kann das und generiert auch korrekten Code dafuer
(der reserviert Platz auf dem Stack und kopiert die Daten dorthin).
Blink mag aber anscheinend nicht, dass die Referenz auf die Originaldaten
keinen Namen hat. Also wirklich ein Blink-Problem...

> -Markus

Gerald Malitz

unread,
Jun 25, 1992, 4:26:49 PM6/25/92
to
Im Artikel <wTvfr*f...@germal.bs.open.de>, schrieb ich gerade:

> Du kannst ja mal das .lnk-File edieren, dort cres.o
> durch c.o ersetzen und `blink with dein.lnk' eingeben

Garrr, jetzt weiss ich's :) "There should be no absolute
references to writeable data." (Seite C13). Der Linker versucht
Dir nur zu sagen, dass Du in Deinem Object-Code eine absolute
Referenz auf die Daten hast, was Du in residenten Programmen
vermeiden solltest. Das ist aber in diesem Falle voellig ok.
Es wird ja garantiert immer nur gelesen. So, don't panic :^)

Andreas M. Kirchwitz

unread,
Jun 27, 1992, 1:47:35 PM6/27/92
to
In article <wTvfr*f...@germal.bs.open.de>, Gerald Malitz writes:

> ??????Ich fuerchte, nein. Wie geschrieben, der Compiler ist


> unschuldig. Du kannst ja mal das .lnk-File edieren, dort cres.o
> durch c.o ersetzen und `blink with dein.lnk' eingeben :) Ich
> glaube, die Meldungen des Linkers kann Andreas getrost ignorieren.

Hmm, okay... ich nehm Dich beim Wort ;-)

> Ich jedenfalls mach mir wegen der Option -O mehr sorgen ;)

Der Optimizer vom Unix-cc ist in der Tat grausam, aber der von SAS/C hat
mir bisher ganz gut gefallen. Gibt es denn spezielle Sachen,
die der GO mit Sicherheit falsch macht? Was waere denn mal ein Stueck
Source, bei dem der GO Zufallscode erzeugt? *neugier*
(ja klar, ich lese csa.pro*, aber dort sind die Leute immer so oft der
Meinung, dass jeder Absturz eines Programms ausschliesslich Schuld des
Compilers/Linkers ist -- an einem bereits fehlerhaften Source kann's ja
uuuuuuuunmoeglich liegen ;-) :-) ;-)

Was mich beim GO fasziniert: er erzeugt tatsaechlich schnelleren und
kuerzeren Code zugleich (vor allem erzeugt er bei "Optimize Time" (bei
mir default) oftmals kuerzeren Code als bei "Optimize Space". Oder be-
zieht sich "Optimize Space" auf die Laufzeit?)

GO ist in jedem Fall ein faszinierendes Programm, hehe... Andreas

--
Andreas M. Kirchwitz, Seesener Str. 69, W-1000 Berlin 31, Germany, | IRC-Nick:
Phone: +49 (0)30 873376, E-Mail: amk@{zikzak.in|cs.tu|fu}-berlin.de | `bonzo'

Andreas M. Kirchwitz

unread,
Jun 27, 1992, 1:53:32 PM6/27/92
to
In article <FAwfr*g...@germal.bs.open.de>, Gerald Malitz writes:

> Im Artikel <wTvfr*f...@germal.bs.open.de>, schrieb ich gerade:
>
> > Du kannst ja mal das .lnk-File edieren, dort cres.o
> > durch c.o ersetzen und `blink with dein.lnk' eingeben
>
> Garrr, jetzt weiss ich's :)

Wer ist dieser geheimnisvolle "Garrr"? ;-)

> "There should be no absolute
> references to writeable data." (Seite C13). Der Linker versucht
> Dir nur zu sagen, dass Du in Deinem Object-Code eine absolute
> Referenz auf die Daten hast, was Du in residenten Programmen
> vermeiden solltest. Das ist aber in diesem Falle voellig ok.
> Es wird ja garantiert immer nur gelesen.

Das musst Du mir evtl. genauer erklaeren. Ich dachte, die Daten kommen
auf den Stack. Jedes (auch residente) Programm hat seinen eigenen Stack.
(irgendwer erwaehte was von Prozessor-Stack ... was hat DER denn damit
zu tun?) Weshalb darf man nur lesen, nicht jedoch schreiben?

> So, don't panic :^)

Doch, operative Panik liegt mir gut ;-) ... Andreas

--

Olaf Barthel

unread,
Jun 28, 1992, 4:29:04 PM6/28/92
to
In article <2Umfr*3...@zikzak.in-berlin.de> a...@zikzak.in-berlin.de (Andreas M. Kirchwitz) writes:
>Du meinst, die entsprechenden Funktionen direkt mit den Tags aufrufen?
>Nun, genau das wollte ich eigentlich vermeiden, um nicht bei der Ver-
>wendung von anderen Libraries (z.B. reqtools) unzaehlige *.lib Files
>dazulinken zu muessen ;-)

Mit anderen Worten: Du moechtest nicht die Routinen benutzen, die
die Argumente auf dem Stack erwarten, sondern die ihnen zugrundeliegenden
Funktion, die die Tags als Zeiger auf ein Array in einem Register erhalten.

>> sondern wie ich vermute, die amiga.lib, die Du zum Linken verwendest.
>
>Die "amiga.lib" linke ich zumindest nicht explizit dazu. Meine Link-Zeile
>sieht so aus:
>
> blink FROM LIB:cres.o $(OBJS) TO $(DEST) LIB LIB:lc.lib LIB:reqtools.lib SD SC ND
> ^^^^^^^^^^ ^^^^^^^^^^^^^^^^
> resident das will ich wegkriegen

Aha, dann ist wahrscheinlich die reqtools.lib nicht speziell fuer
small code/small data assembliert worden. Das kann man aendern, schick mir notfalls
den Quellcode fuer die Glue-Routinen und ich werde sehen, was man machen kann.

>Und LIB:cres.o vertraegt sich nicht mit der Initialisierung von Tag-Arrays,
>Strings etc. innerhalb von Funktionen/Prozeduren. Also selbst wenn man das
>Prob mit den Tags umgehen kann (wie z.B. in `term'), wie initialisiere ich
>dann Strings, bleibt die Frage? ;-)

Ich moechte Dir ja nicht Unkenntnis der Dinge vorwerfen (es ist ja schon
haeufiger passiert, dass derjenige, dem dies vorgeworfen wurde, mit flames
gebraten und schliesslich aus seiner Heimatbox geworfen wurde), aber es kann
nicht an den Tags liegen. Folgendes Programm laesst sich mit `lc -L -tr window.c'
korrekt compilieren, linken, resident einbinden und ohne Pruefsummenfehler
mehrfach aufrufen:

#include <intuition/intuitionbase.h>

struct IntuitionBase *IntuitionBase;

void
main()
{
if(IntuitionBase = (struct IntuitionBase *)OpenLibrary("intuition.library",37))
{
struct Window *Window;

if(Window = (struct Window *)OpenWindowTags(NULL,
WA_Width, 100,
WA_Height, 100,
WA_Title, "Fensta",

WA_DepthGadget, TRUE,
WA_DragBar, TRUE,
WA_SizeGadget, TRUE,
WA_CloseGadget, TRUE,

WA_MinWidth, 50,
WA_MinHeight, 50,
WA_MaxWidth, 200,
WA_MaxHeight, 200,

WA_IDCMP, IDCMP_CLOSEWINDOW,
TAG_DONE))
{
struct IntuiMessage *Message;
BYTE Run = TRUE;

do
{
WaitPort(Window -> UserPort);

while(Message = (struct IntuiMessage *)GetMsg(Window -> UserPort))
{
if(Message -> Class == IDCMP_CLOSEWINDOW)
Run = FALSE;

ReplyMsg((struct Message *)Message);
}
}
while(Run);

CloseWindow(Window);
}

CloseLibrary(IntuitionBase);
}
}

Der cres.o Startup-Code hat gerade die Eigenschaft, statische Initialisierungen
`umzulenken', die normalerweise einem Programm, das resident geladen werden soll,
das Genick brechen wuerden.

> Andreas M. Kirchwitz, Seesener Str. 69, W-1000 Berlin 31, FRG, +49 30 873376
> / `__' To: amk@{zikzak.in|cs.tu|methan.chemie.fu}-berlin.de
>/___(oo)_________ Trust me. I know what I'm doing. ___________ IRC-Nick: `bonzo'
> " "

--

Markus Wild

unread,
Jun 28, 1992, 9:49:48 PM6/28/92
to
>... [Rest kommt ohne Tags aus;-))]

>
> Der cres.o Startup-Code hat gerade die Eigenschaft, statische Initialisierungen
>`umzulenken', die normalerweise einem Programm, das resident geladen werden soll,
>das Genick brechen wuerden.

Mag schon sein... nur mit diesem Programm hast Du dies keinesfalls bewiesen;-)
Es braucht eben genau eine Funktion, die Andreas eigentlich *nicht* brauchen
wollte. Ausserdem ist es nicht sonderlich spannend, mach das ganze doch mal
mit variabler Groesse (dh. Width/Height sind Variablen, keine Konstanten),
und benutze ein Tag-Array, wie das zu Beginn mal gewuenscht wurde, und dann
schauen wir mal, ob SAS immernoch klar kommt... (gespannt sei ;-))

Andreas M. Kirchwitz

unread,
Jun 28, 1992, 10:31:41 PM6/28/92
to
In article <olsen...@sourcery.mxm.sub.org>, Olaf Barthel writes:

> Ich moechte Dir ja nicht Unkenntnis der Dinge vorwerfen (es ist ja schon
> haeufiger passiert, dass derjenige, dem dies vorgeworfen wurde, mit flames
> gebraten und schliesslich aus seiner Heimatbox geworfen wurde), aber es kann
> nicht an den Tags liegen.

Ich habe in der Tat wenig Kenntnis ;-)
("Freuet Euch dass, fraget nicht warum", hehe)

> Folgendes Programm laesst sich mit `lc -L -tr window.c'
> korrekt compilieren, linken, resident einbinden und ohne Pruefsummenfehler
> mehrfach aufrufen:

> [funktionierendes Programmbeispiel mit Tags geloescht]

Source:

#include <stdio.h>
#include <stdlib.h>

int main(int argc, char *argv[])
{
char text[] = "Hello World\n";
printf("%s",text);
exit(10);
}

Optionen: <keine>
Compiler: lc test.c
Linker : blink FROM LIB:cres.o test.o TO test LIB LIB:lc.lib SD SC ND

"Warning! Absolute reference to UNKNOWN" ... Andreas


PS: Ersetz den String durch TagItems oder sonstwas...
Die Warning bleibt. Das Programm laeuft auf den ersten Blick normal.
GIB WARNINGS KEINE CHANCE!
(wollte damit eigentlich nur demonstrieren, dass das Problem nichts
speziell mit TagItems oder der reqtools.lib zu tun hat ;-)

PPS: Kann man beim BLink eigentlich bestimmte Warnings (ausser mit "grep")
unterdruecken?


PPPS: Interessante Effekte erhaelt man, wenn man 'printf("%s",text);'
durch 'printf(text);' ersetzt. Eindrucksvoller Memory-Dump...
Anscheinend ist die Warning eine warnende Warning, der man doch
besser Beachtung schenken sollte.


--
IRC-Nick: | Andreas M. Kirchwitz, Seesener Str. 69, W-1000 Berlin 31, Germany
`bonzo' | Phone: +49 (0)30 873376, Mail: amk@{zikzak.in|cs.tu|fu}-berlin.de

Franz-Josef Reichert

unread,
Jun 29, 1992, 9:10:06 PM6/29/92
to
In article <olsen...@sourcery.mxm.sub.org>, Olaf Barthel writes:

> In article <2Umfr*3...@zikzak.in-berlin.de> a...@zikzak.in-berlin.de (Andreas M. Kirchwitz) writes:
> >Du meinst, die entsprechenden Funktionen direkt mit den Tags aufrufen?
> >Nun, genau das wollte ich eigentlich vermeiden, um nicht bei der Ver-
> >wendung von anderen Libraries (z.B. reqtools) unzaehlige *.lib Files
> >dazulinken zu muessen ;-)
> Mit anderen Worten: Du moechtest nicht die Routinen benutzen, die
> die Argumente auf dem Stack erwarten, sondern die ihnen zugrundeliegenden
> Funktion, die die Tags als Zeiger auf ein Array in einem Register erhalten.

Jetzt mal ernsthaft! Welchen Sinn macht es denn, sich
die Tags vom Compiler auf den Stack befoerdern zu lassen, indem man sie
als 'automatic' Daten definiert? Das erzeugt zum einen Code, und zum
anderen erreicht man damit _exakt_ denselben Effekt, als wenn man sie
an einen Varargs-Stub uebergeben wuerde. Also bitte, wer schon TagItem-
ARRAY's anlegen will, der soll's doch bitte _statisch_ tun! Das tut
einer moeglicherweise gewuenschten Reentrancy solange keinen Abbruch,
wie sie 'const' definiert und benutzt werden, was zusaetzlich noch
den netten Nebeneffekt hat, dem Compiler eine Optimierungschance
mehr einzuraeumen. Und Bezeichnerkonflikten geht man aus dem Weg,
indem man solche Konstrukte innerhalb des Funktionskoerpers explizit
als 'static' deklariert. Wessen TagItems sowohl mit konstanten Daten
wie auch erst sich zur Laufzeit ergebenden dynamischen Werten gefuellt
werden muessen, wird ohnehin an der statischen Deklaration wenig Freude
haben und von vorneherein die Varags-Alternative bevorzugen. Man kann
auch beides mixen, indem man am Ende einer Kette von dynamischen
Varargs-Initialisierungen mit TAG_MORE statt TAG_END einen Zeiger
auf ein statisch initialisiertes (konstantes) Tag-Array uebergibt.
Solange das nicht in Konflikt mit einer zwingenden Tag-Reihenfolge
steht, jedenfalls.

Ich kann also nicht nachvollziehen, welche tiefere
Bedeutung dem Ansinnen zukommt, zur Laufzeit 'automatic' Tagarrays
anlegen zu wollen? m.E. bringt das keine zusaetzlichen Vorteile.

> >Und LIB:cres.o vertraegt sich nicht mit der Initialisierung von Tag-Arrays,
> >Strings etc. innerhalb von Funktionen/Prozeduren. Also selbst wenn man das
> >Prob mit den Tags umgehen kann (wie z.B. in `term'), wie initialisiere ich
> >dann Strings, bleibt die Frage? ;-)

Strings initialisiert man in C gemeinhin _immer_ statisch.
Zur Laufzeit geht das nur mit strcpy() e.a..

> > Andreas M. Kirchwitz, Seesener Str. 69, W-1000 Berlin 31, FRG, +49 30 873376

--
Best regards,
Franz-Josef Reichert GERMANY - VOICE: +49 6805 7417
Kuchlingerstrasse 13 UUCP: fjrei@kbsaar.{saar|adsp}.sub.org
6601 Kleinblittersdorf fj...@kbsaar.saar.de

Andreas M. Kirchwitz

unread,
Jun 30, 1992, 8:06:23 AM6/30/92
to
In <KlTgr*C...@kbsaar.saar.sub.org> fj...@kbsaar.saar.sub.org (Franz-Josef Reichert) writes:

> Strings initialisiert man in C gemeinhin _immer_ statisch.

Ach ja? Ist mir neu...

>Zur Laufzeit geht das nur mit strcpy() e.a..

Mitnichten.

Mit Unverstaendnis... Andreas

Gerald Malitz

unread,
Jun 29, 1992, 3:54:21 PM6/29/92
to
In article <nr8gr*S...@zikzak.in-berlin.de>, Andreas M. Kirchwitz writes:

> In article <wTvfr*f...@germal.bs.open.de>, Gerald Malitz writes:
>
> > ??????Ich fuerchte, nein. Wie geschrieben, der Compiler ist
> > unschuldig. Du kannst ja mal das .lnk-File edieren, dort cres.o
> > durch c.o ersetzen und `blink with dein.lnk' eingeben :) Ich
> > glaube, die Meldungen des Linkers kann Andreas getrost ignorieren.
>
> Hmm, okay... ich nehm Dich beim Wort ;-)

Nur zu.

> > Ich jedenfalls mach mir wegen der Option -O mehr sorgen ;)
>
> Der Optimizer vom Unix-cc ist in der Tat grausam, aber der von SAS/C hat
> mir bisher ganz gut gefallen. Gibt es denn spezielle Sachen,
> die der GO mit Sicherheit falsch macht?

Definitiv ja.

> Was waere denn mal ein Stueck
> Source, bei dem der GO Zufallscode erzeugt? *neugier*

Naja, so wild ist's nun gerade nicht. Auf den Native-
Developer-Disketten sind u. a. auch die Sourcen zum play8svx.
Dazu gehoert (logisch) eine Routine, die den Ton laedt. In der
meint der GO ein Register fuer zwei Variablen benutzen zu koennen :)
Das faellt deswegen sehr schnell auf, weil diese Funktion mit GO
optimiert immer einen Wert != 0 liefert, was eigentlich bedeutet,
dass der Sound nicht geladen werden konnte. Hier also relativ
harmlos, aber...

> GO ist in jedem Fall ein faszinierendes Programm, hehe... Andreas

Faszinierend sind vorallem die Effekte, die GOptimierte
Programme erzeugen :), Gerald.

Markus Wild

unread,
Jun 30, 1992, 7:42:20 PM6/30/92
to
In article <JcBgr*r...@zikzak.in-berlin.de> a...@zikzak.in-berlin.de (Andreas M. Kirchwitz) writes:
>#include <stdio.h>
>#include <stdlib.h>
>
>int main(int argc, char *argv[])
>{
> char text[] = "Hello World\n";
> printf("%s",text);
> exit(10);
>}
>
>Optionen: <keine>
>Compiler: lc test.c
>Linker : blink FROM LIB:cres.o test.o TO test LIB LIB:lc.lib SD SC ND
>
> "Warning! Absolute reference to UNKNOWN" ... Andreas

Hat vermutlich damit zu tun, dass SAS String-Konstanten grundlos in den
DATA Hunk wirft, und damit zu veraenderlichen Objekten erklaert. Wenn
die String-Konstante "Hello World\n" (und nicht etwa text!) im CODE Hunk
waere, haette BLink gar nix zu motzen, denn dann haette er keine data-text
Relokation auszufuehren, die ja in einem resident-faehigen Programm nicht
auftreten sollte.

>PPS: Kann man beim BLink eigentlich bestimmte Warnings (ausser mit "grep")
> unterdruecken?

Groel.. BLink als Manifestation der AmigaDOS treuen Gemeinde, die sich
gern duselig quatscht auf der Kommandozeile (und daher Optionen ala -s -o
und dergleichen verdammt), wird mit einem Unix Programm (grep) zu
Leibe gerueckt, finde ich einfach koestlich ;-)

>PPPS: Interessante Effekte erhaelt man, wenn man 'printf("%s",text);'
> durch 'printf(text);' ersetzt. Eindrucksvoller Memory-Dump...
> Anscheinend ist die Warning eine warnende Warning, der man doch
> besser Beachtung schenken sollte.

Absolut unklar, weshalb das zu Problemen fuehren soll?! Die interne
Referent auf die String-Konstante ist doch in beiden Faellen 100%
gleich? Im beiden Faellen sollte die Konstante als Source in einem
bcopy()/memmove() (oder inline kopiert) auf die Stack-Variable dienen,
der einzige Unterschied ist, dass im ersten Fall nach dem Push der
Stackadresse noch ein Push der Adresses des Format-Strings vorgeht, ent-
scheidet dies bei SAS ueber Crash oder nicht-Crash??

Markus Wild

unread,
Jun 30, 1992, 7:55:26 PM6/30/92
to
In article <KlTgr*C...@kbsaar.saar.sub.org> fj...@kbsaar.saar.de (Franz-Josef Reichert) writes:
> Jetzt mal ernsthaft! Welchen Sinn macht es denn, sich
>die Tags vom Compiler auf den Stack befoerdern zu lassen, indem man sie
>als 'automatic' Daten definiert? Das erzeugt zum einen Code, und zum
>anderen erreicht man damit _exakt_ denselben Effekt, als wenn man sie
>an einen Varargs-Stub uebergeben wuerde. Also bitte, wer schon TagItem-

Jein... der Effekt ist gleich, nur muss ich im einen Fall ne giganteske
Library (sprich amiga.lib) dazu linken, die ausserdem noch von Commodore
mit zweifelhaften `Perlen' ala voellig inkompatibler stdio-Funktionalitaet
bereicht wuerde, und im andern Fall halt nicht!

>ARRAY's anlegen will, der soll's doch bitte _statisch_ tun! Das tut

Noe.. laengst nicht alle Tag-Arrays sind statisch, und wenn Du beginnst,
statische Arrays dann nachtraeglich doch noch zur Laufzeit zu aendern (und
das ueblicherweise natuerlich nicht durch Semaphoren schuetzt), dann ist
die Reentrancy zum Teufel.

>einer moeglicherweise gewuenschten Reentrancy solange keinen Abbruch,
>wie sie 'const' definiert und benutzt werden, was zusaetzlich noch
>den netten Nebeneffekt hat, dem Compiler eine Optimierungschance
>mehr einzuraeumen. Und Bezeichnerkonflikten geht man aus dem Weg,

Schon klar, dass const Objekte huebsche Hinweise fuer den Compiler beinhalten,
nur gibtst Du diesem dadurch, dass Du die Objekte in statischen Speicher
forcierst (!) keine Chance, sie gaenzlich inline zu expandieren, was ich
schade finde.

> Ich kann also nicht nachvollziehen, welche tiefere
>Bedeutung dem Ansinnen zukommt, zur Laufzeit 'automatic' Tagarrays
>anlegen zu wollen? m.E. bringt das keine zusaetzlichen Vorteile.

Siehe oben. Ausserdem, je mehr Daten Du dem Compiler zur Verfuegung stellst,
aus denen er versuchen kann, das Optimum rauszuholen, desto besseren Code
wird er erzeugen. In diesem Fall (jetzt mal von dynamischen Daten aus-
gehend) hat er entweder die Wahl, zu einem bestimmten Zeitpunkt alle
Werte zu instantiieren und per Stack an die Varargs Funktion zu uebergeben
(womit a0/a1/d0/d1 ja wegfallen als Datentraeger), oder sie womoeglich
ohne Umwege direkt nach erfolgter Berechnung in die spaeter der OS-Funktion
zu uebergebende Tag-Struktur zu schreiben. Aus diesem Blickwinkel kriegst
Du mit der Varargs-Version garantiert die schlechteste Loesung, auch wenn
nicht garantiert ist, dass die andere Variante besser ist.

> Strings initialisiert man in C gemeinhin _immer_ statisch.
>Zur Laufzeit geht das nur mit strcpy() e.a..

Ooch.. bist Du aber K&R treu.. nur weil das immer so war, muss das doch
nicht immer so bleiben?! Es ist doch durchaus huebsch, mktemp(3) so
zu implementieren:
char template[] = "ram:t/tmpl.XXXXXX";

/* und jetzt template aendern, bis es eindeutig ist */

als da erst umstaendlich die Laenge von template abzuzaehlen, als
Array Groesse anzugeben (oder wie ueblich mal ueberrissene 255 Zeichen
zu verwenden, weil man zum abzaehlen eh zu faul ist;-)), und dann noch
mit strcpy() das template auszufuellen. Die ANSI-Variante sieht nicht
nur schoener aus, sondern ist auch einfacher zu verwenden, IMHO ;-)

Andreas M. Kirchwitz

unread,
Jul 1, 1992, 8:25:53 AM7/1/92
to

>>PPPS: Interessante Effekte erhaelt man, wenn man 'printf("%s",text);'
>> durch 'printf(text);' ersetzt. Eindrucksvoller Memory-Dump...
>> Anscheinend ist die Warning eine warnende Warning, der man doch
>> besser Beachtung schenken sollte.
>
>Absolut unklar, weshalb das zu Problemen fuehren soll?!

Nicht nur Dir -- aber mit printf(text) geht's einfach nicht...
(mehrmals auf die eine Art compiliert, mehrmals auf die andere)

>der einzige Unterschied ist, dass im ersten Fall nach dem Push der
>Stackadresse noch ein Push der Adresses des Format-Strings vorgeht, ent-
>scheidet dies bei SAS ueber Crash oder nicht-Crash??

Na, anscheinend :-( ... Andreas


PS: Im Prinzip kann man dem Compiler nur einen geringen Vorwurf machen,
denn er zwingt zu besserem Programmieren: printf("<text>") sollte
man sowieso nicht verwenden :-)

Martin Hohl

unread,
Jun 30, 1992, 7:18:23 AM6/30/92
to
In article <nr8gr*S...@zikzak.in-berlin.de> a...@zikzak.in-berlin.de (Andreas M. Kirchwitz) writes:
AK> Der Optimizer vom Unix-cc ist in der Tat grausam, aber der von SAS/C hat
AK> mir bisher ganz gut gefallen. Gibt es denn spezielle Sachen,
AK> die der GO mit Sicherheit falsch macht? Was waere denn mal ein Stueck
AK> Source, bei dem der GO Zufallscode erzeugt? *neugier*
AK>
AK> Was mich beim GO fasziniert: er erzeugt tatsaechlich schnelleren und
AK> kuerzeren Code zugleich (vor allem erzeugt er bei "Optimize Time" (bei
AK> mir default) oftmals kuerzeren Code als bei "Optimize Space". Oder be-
AK> zieht sich "Optimize Space" auf die Laufzeit?)
AK>

Der SAS Global Optimizer (GO) kann in speziellen Faellen auch ein
"Global Pessimizer" ;-) sein (sprich: die Laufzeit des Compilats
erhoeht sich). (Speziell bei Postinkrement-Adressierung).

AK> GO ist in jedem Fall ein faszinierendes Programm, hehe... Andreas
In der Tat ... ;-)

In einem speziellen Fall (tr2tex) hatte ich das Problem, dasz GO
sogar falschen Code erzeugt (ohne -O Option in tr.c geht's einwandfrei).

Ciao !
--

| | Martin Hohl mar...@solaris.tynet.sub.org
|\_/| Robert-Leicht-Str. 132, 7000 Stuttgart 80, FRG
| "Der Usus der Entagonyme ist prinzipiell auf ein
| Minimum zu reduzieren."

Franz-Josef Reichert

unread,
Jul 1, 1992, 7:40:39 AM7/1/92
to
In article <1992Jun30.2...@bernina.ethz.ch>, Markus Wild writes:

> Jein... der Effekt ist gleich, nur muss ich im einen Fall ne giganteske
> Library (sprich amiga.lib) dazu linken, die ausserdem noch von Commodore
> mit zweifelhaften `Perlen' ala voellig inkompatibler stdio-Funktionalitaet
> bereicht wuerde, und im andern Fall halt nicht!

Dieses Problem (sofern es eins ist) kann einfach umschifft
werden, indem man sich den Varargs-Stub _selbst_ schreibt. Niemand muss
mit amiga.lib linken, wenn er nicht will.



> >ARRAY's anlegen will, der soll's doch bitte _statisch_ tun! Das tut
>
> Noe.. laengst nicht alle Tag-Arrays sind statisch, und wenn Du beginnst,
> statische Arrays dann nachtraeglich doch noch zur Laufzeit zu aendern (und
> das ueblicherweise natuerlich nicht durch Semaphoren schuetzt), dann ist
> die Reentrancy zum Teufel.

Das sollte man natuerlich nicht! Deswegen ja auch der
folgende Absatz! Bitte nicht mehr sinnentstellend quoten! Ich sagte
keineswegs, dass statische Tag-Arrays _immer_ Sinn machen. Es kommt
auf das Wort "solange" (s.u.) an. Fuer solche Faelle hatte ich ausserdem
vorgeschlagen, Varargs und statische Tags zu mischen, falls moeglich.

> >einer moeglicherweise gewuenschten Reentrancy solange keinen Abbruch,
> >wie sie 'const' definiert und benutzt werden, was zusaetzlich noch
> >den netten Nebeneffekt hat, dem Compiler eine Optimierungschance
> >mehr einzuraeumen. Und Bezeichnerkonflikten geht man aus dem Weg,
>
> Schon klar, dass const Objekte huebsche Hinweise fuer den Compiler beinhalten,
> nur gibtst Du diesem dadurch, dass Du die Objekte in statischen Speicher
> forcierst (!) keine Chance, sie gaenzlich inline zu expandieren, was ich
> schade finde.

Was ist "schade"? Beschreibe doch mal bitte, was diese
"Inline expansion", was immer damit gemeint sei, in diesem Zusammenhang
an Vorteilen bringt? Ich kann nicht nachvollziehen, inwieweit man die
Zusammenstellung von Daten optimieren kann, die bereits in einer Form
vorliegen, dass man sie 1:1 aus dem Lademodul uebernehmen kann. Unter
der Voraussetzung, dass die verarbeitende Funktion einen _Pointer_ auf
diese Daten erwartet, versteht sich.

> > Ich kann also nicht nachvollziehen, welche tiefere
> >Bedeutung dem Ansinnen zukommt, zur Laufzeit 'automatic' Tagarrays
> >anlegen zu wollen? m.E. bringt das keine zusaetzlichen Vorteile.
>
> Siehe oben. Ausserdem, je mehr Daten Du dem Compiler zur Verfuegung stellst,
> aus denen er versuchen kann, das Optimum rauszuholen, desto besseren Code
> wird er erzeugen.

Redundanzen koennen nie zu mehr als 100% entfernt werden.
Also der gleiche Effekt, als wenn man sie erst gar nicht erzeugt
(was ich versuche, zu propagieren). Darueber den _Compiler_ brueten
zu lassen, erachte ich zumindest als ineffizient (da kommt halt der
Oekonom durch, Informatiker moegen sich an solchen Effekten schon
aus rein wissenschaftlichem Interesse ergoetzen). Es ist zwar schoen,
wenn ein Compiler sowas kann, aber koennte er in dieser Zeit nichts
Sinnvolleres anstellen? Die Rechnung "Mehr Code => Mehr Optimierung"
scheint mir jedenfalls _etwas_ widerspruechlich! :-)

> In diesem Fall (jetzt mal von dynamischen Daten aus-
> gehend) hat er entweder die Wahl, zu einem bestimmten Zeitpunkt alle
> Werte zu instantiieren und per Stack an die Varargs Funktion zu uebergeben
> (womit a0/a1/d0/d1 ja wegfallen als Datentraeger), oder sie womoeglich
> ohne Umwege direkt nach erfolgter Berechnung in die spaeter der OS-Funktion
> zu uebergebende Tag-Struktur zu schreiben. Aus diesem Blickwinkel kriegst
> Du mit der Varargs-Version garantiert die schlechteste Loesung, auch wenn
> nicht garantiert ist, dass die andere Variante besser ist.

- a0/a1/d0/d1 fallen frueher oder spaeter _immer_ weg, denn
wir wollen ja eine Systemfunktion -direkt oder indirekt- aufrufen.

- Die Werte werden auf dem Stack uebergeben, und da _bleiben_
sie dann auch, weil der Stack damit zum TagArray _wird_.

- 'automatic'-Variablen werden gemeinhin _auch_ nirgendwo
anders als auf dem Stack instantiiert. Jede Abweichung
hiervon erzeugt _nochmals_ zusaetzlichen Code zur Speicher-
beschaffung, Verwaltung und abschliessender Freigabe.

- Die Schlussfolgerung ist in diesem Zusammenhang falsch.

> > Strings initialisiert man in C gemeinhin _immer_ statisch.
> >Zur Laufzeit geht das nur mit strcpy() e.a..
>
> Ooch.. bist Du aber K&R treu.. nur weil das immer so war, muss das doch
> nicht immer so bleiben?!

Was gewinnt man durch die automatic-Deklaration von Strings?
Ein _builtin_strcpy() vom (in diesem Falle dann _doch_ wieder statisch
initialisierten) DATA-Segment auf den Stack? Doppelter Speicherbedarf,
zusaetzlicher Code! (Womit nicht gesagt sein soll, dass es fuer diesen
Mehraufwand niemals eine Rechtfertigung geben mag). Ich bin nur sehr
vorsichtig mit "Segnungen" dieser Art. Wer zeitkritische Applikationen
schreibt, mag hunderte von builtin-Funktionen und damit verbundene
Codegenerierung erdulden [nur am Rande: strcpy() ist m.E. _selten_ der
ideale Ansatzpunkt fuer Optimierungen], ansonsten erzeugen Funktionsaufrufe
aber regelmaessig _kuerzeren_ Code. Keine Frage "K&R vs. ANSI" sondern ganz
einfach "Effizienz vs. Komfort"!

> Es ist doch durchaus huebsch, mktemp(3) so
> zu implementieren:
> char template[] = "ram:t/tmpl.XXXXXX";

"Huebsch" ist eine subjektive Empfindung. Tatsache ist, dass
im fertigen Objektmodul sowohl der initiale Stringinhalt im DATA-
Segment steht, zum Funktionseintritt als erstes von dort auf den
Stack _umkopiert_ wird, um dann gleich wieder in subsequenten
Konstrukten _ueberschrieben_ zu werden. Da bleibt die Effizienz doch
irgendwo auf der Strecke, findest Du nicht? Selbst unter der Annahme,
dass der erste Schritt "wegoptimiert" wird (der Compiler finde irgendwie
(?) heraus, dass der initiale Inhalt von template[] nicht benoetigt werde),
gewinnt man mit dieser Moeglichkeit unterm Strich _nichts_.

> [...] Die ANSI-Variante sieht nicht


> nur schoener aus, sondern ist auch einfacher zu verwenden, IMHO ;-)

Die Frage lautet halt immer: "Wieviel Bytes ist Dir
Deine Faulheit wert" :-) :-).

--

Franz-Josef Reichert

unread,
Jul 1, 1992, 10:03:38 AM7/1/92
to
In article <1992Jun30....@cs.tu-berlin.de>, Andreas M. Kirchwitz writes:

> In <KlTgr*C...@kbsaar.saar.sub.org> fj...@kbsaar.saar.sub.org (Franz-Josef Reichert) writes:
>
> > Strings initialisiert man in C gemeinhin _immer_ statisch.
>
> Ach ja? Ist mir neu...

Initialisierung = VORbelegung von Speicherzellen mit bestimmten
Inhalten.

Statisch = i.S.v. Wertbestimmung _vor_ der Laufzeit.

Mit "statischer Initialisierung" bezeichne ich demnach, dass bei
allen Stringinitialisierungen der resultierende String-Inhalt bereits _vor_
der Laufzeit festzustehen hat, das "immer" impliziert, dass es in 'C' nicht
anders moeglich ist. Was einfach daran liegt, dass C i.d.R. compiliert, nicht
interpretiert wird. Was ist daran unklar? Wie kann ich etwas "VORbelegen",
wenn ich zum Zeitpunkt der VORbelegung noch gar nicht weiss, welche Werte
das vorzubelegende Objekt erhalten soll? Das waere doch ein ganz klarer
Widerspruch!

> >Zur Laufzeit geht das nur mit strcpy() e.a..
>
> Mitnichten.

Was Du meinst, ist "dynamisches Ausfuellen von Stringinhalten".
In der Praxis laeuft dies aber immer auf ein (bestenfalls) inline-strcpy()
hinaus, dessen Quelldaten in den meisten Faellen auch noch aus statischen
Daten bedient werden. Sobald ich im C-Source irgendwas zwischen doppelte
Anfuehrungszeichen setze, kann ich davon ausgehen, dass der Compiler daraus
auch statische Daten erzeugt. Womit ich statische Daten gewinne, nicht
aber vermeide. Der signifikante Unterschied zwischen (1)

test1() {
unsigned char string[] = "Laberfasel";
}

und (2)

test2() {
static unsigned char string[] = "Laberfasel";
}

ist nunmal, dass (2) _weniger_ Code erzeugen _muss_!

> Mit Unverstaendnis... Andreas

Ueber mangelhafte Effizienz des (dynamischen) Umkopierens (aus
ihrer Definition heraus bereits) statischer Dateninhalte braucht aber nicht
diskutiert zu werden? Oder etwa doch? :-)

Markus Wild

unread,
Jul 2, 1992, 12:52:59 PM7/2/92
to
In article <WMnhr*3...@kbsaar.saar.sub.org> fj...@kbsaar.saar.de (Franz-Josef Reichert) writes:
> Initialisierung = VORbelegung von Speicherzellen mit bestimmten
> Inhalten.

Schon.. aber das VOR heisst in diesem Falle nur, dass das geschehen muss
bevor diese Speicherquellen benutzt werden, es heisst aber keineswegs,
dass die Initialisierung zur Compile-Zeit geschehen muss. Sehr gutes
Beispiel fuer das Gegenteil sind C++ Constructors, die globale Daten
initialisieren sollen. Da spricht doch niemand von `Wertbestimmung' oder
aehnlichem...

> Statisch = i.S.v. Wertbestimmung _vor_ der Laufzeit.

i.S.v. gleich "im Schweisse von" oder was?

>allen Stringinitialisierungen der resultierende String-Inhalt bereits _vor_
>der Laufzeit festzustehen hat, das "immer" impliziert, dass es in 'C' nicht
>anders moeglich ist. Was einfach daran liegt, dass C i.d.R. compiliert, nicht
>interpretiert wird. Was ist daran unklar? Wie kann ich etwas "VORbelegen",
>wenn ich zum Zeitpunkt der VORbelegung noch gar nicht weiss, welche Werte
>das vorzubelegende Objekt erhalten soll? Das waere doch ein ganz klarer
>Widerspruch!

Haengt von der Definition Deines 'VOR's ab.

> Was Du meinst, ist "dynamisches Ausfuellen von Stringinhalten".
>In der Praxis laeuft dies aber immer auf ein (bestenfalls) inline-strcpy()
>hinaus, dessen Quelldaten in den meisten Faellen auch noch aus statischen
>Daten bedient werden. Sobald ich im C-Source irgendwas zwischen doppelte
>Anfuehrungszeichen setze, kann ich davon ausgehen, dass der Compiler daraus
>auch statische Daten erzeugt. Womit ich statische Daten gewinne, nicht
>aber vermeide. Der signifikante Unterschied zwischen (1)

Also.. jedes Ding am richtigen Platz, ok?

{ char *foo = "bar"; }
Der Pointer foo ist aenderbar, nicht aber der Inhalt "bar", der ist
Konstant. Durch aendern von foo wird eine verschachtelte Funktion nicht
beintraechtigt (Block-Scope).

{ char foo[] = "bar"; }
Der Pointer foo ist nicht aenderbar (da Array), wohl aber sein Inhalt.
Auch Block-Scope.

static *foo = "bar";
Siehe oben, nur hat das Ding Global-Scope (ob der dann dadurch
eingeschraenkt ist, ob das Ding nu in einer Funktion drin steht ist
belanglos).

static foo[] = "bar";
Dito fuer Nummer 2.

> Ueber mangelhafte Effizienz des (dynamischen) Umkopierens (aus
>ihrer Definition heraus bereits) statischer Dateninhalte braucht aber nicht
>diskutiert zu werden? Oder etwa doch? :-)

Ich moechte einfach vermeiden, dass wir hier Aepfel mit Birnen vergleichen.
Entweder Deine Strings sind konstant, dann wird `man' Pointers
verwenden. Sind Deine Strings nicht konstant, kommst Du um die Arrays
nicht rum, wenn Du nicht per malloc() Speicher ranschaffen willst, was aber
in Deinen Effizienzueberlegungen sowieso durchfallen wuerde. Da wir hier
ja grundsaetzlich nur von den String-Arrays, nicht aber von den Pointern
gesprochen haben, ist Deine Kritik deplaziert. In den von Dir gebrachten
Beispielen waeren (statische oder nicht) Pointer eher angebracht als
Arrays. Dass man fuer Array-Initialisierung '=' verwendet, und nicht
strcpy(), muesste doch klar sein, oder?

-Markus
--

Markus Wild

unread,
Jul 2, 1992, 1:37:04 PM7/2/92
to
In article <TGlhr*2...@kbsaar.saar.sub.org> fj...@kbsaar.saar.de (Franz-Josef Reichert) writes:
>In article <1992Jun30.2...@bernina.ethz.ch>, Markus Wild writes:
>
>> Jein... der Effekt ist gleich, nur muss ich im einen Fall ne giganteske
>> Library (sprich amiga.lib) dazu linken, die ausserdem noch von Commodore
>> mit zweifelhaften `Perlen' ala voellig inkompatibler stdio-Funktionalitaet
>> bereicht wuerde, und im andern Fall halt nicht!
>
> Dieses Problem (sofern es eins ist) kann einfach umschifft
>werden, indem man sich den Varargs-Stub _selbst_ schreibt. Niemand muss
>mit amiga.lib linken, wenn er nicht will.

Nuja, also mal davon ausgehend, dass uns der Varargs-Support von
amiga.lib beschert wurde, und nicht ein offizieller Einsprung in die
Library ist, finde ich eine Implementation mit Tag Arrays schoener.

> Das sollte man natuerlich nicht! Deswegen ja auch der
>folgende Absatz! Bitte nicht mehr sinnentstellend quoten! Ich sagte

Sowas liegt mir aber wirklich fern, ich versuche jeweils die Msgs
soweit zu trimmen, dass nur das wichtigste gequotet ist, sonst ent-
wickeln sich wirklich bald Romaene aus Msgs...

> Was ist "schade"? Beschreibe doch mal bitte, was diese
>"Inline expansion", was immer damit gemeint sei, in diesem Zusammenhang

Kleines Beispiel gefaellig?

#define va_expand(valist) valist##,
#define AllocAslRequestTags(type, tags...) \
({ ULONG _tags[] = { va_expand(tags) TAG_DONE,0 }; \
AllocAslRequest (type, (struct TagItem *) _tags); })

(Ausm Gedaechtnis, bitte nicht auf Details festnageln ;-))
Womit Du ohne Funktionsaufruf der Varargs-Funktion direkt in die
Library springen kannst. Wenn Du dem User aufbuerden willst, jedesmal
ans TAG_DONE zu denken, kannst Du Dir auch den Expand-Trick schenken,
der nur dafuer sorgt, dass nie sowas wie { ,TAG_DONE,0 } entsteht.

>an Vorteilen bringt? Ich kann nicht nachvollziehen, inwieweit man die
>Zusammenstellung von Daten optimieren kann, die bereits in einer Form
>vorliegen, dass man sie 1:1 aus dem Lademodul uebernehmen kann. Unter

Wir sind in erster Linie von dynamischen (!) Tags ausgegangen, nicht
von statischen Tabellen, fuer die's ja absolut keinen Sinn macht,
sie umzukopieren. Die dynamischen Daten haben aber in der Regel nicht
die Eigenschaft, 1:1 in einem Lademodul rumzulungern, sonst waeren sie
naemlich nicht dynamisch...

> Redundanzen koennen nie zu mehr als 100% entfernt werden.
>Also der gleiche Effekt, als wenn man sie erst gar nicht erzeugt

Du gehst davon aus, dass genau eine Loesung existiert, aus gegebener
Source Assembly zu erstellen. Dem ist aber in der Regel nicht so.. In gewissen
Faellen kann eine andere Datensammlung, die Du dem Compiler zum
Verarbeiten auf den Weg gibst, zu einem total anderem Resultat fuehren.

>(was ich versuche, zu propagieren). Darueber den _Compiler_ brueten
>zu lassen, erachte ich zumindest als ineffizient (da kommt halt der

Och, also aus Spass an der Freud geb ich meinem Compiler in der Regel
auch keine Puzzles auf. Aber in gewissen Faellen ist es durchaus
angebracht, gewisse Hinweise auf moegliche Optimierungen reinzu-
programmieren, so den Compiler ein bischen zu lenken...

>Oekonom durch, Informatiker moegen sich an solchen Effekten schon
>aus rein wissenschaftlichem Interesse ergoetzen). Es ist zwar schoen,

Auch, auch ;-))

>wenn ein Compiler sowas kann, aber koennte er in dieser Zeit nichts
>Sinnvolleres anstellen? Die Rechnung "Mehr Code => Mehr Optimierung"
>scheint mir jedenfalls _etwas_ widerspruechlich! :-)

Muss nicht notwendigerweise mehr Code heissen, aber oft ist es schon
so...

> - a0/a1/d0/d1 fallen frueher oder spaeter _immer_ weg, denn
> wir wollen ja eine Systemfunktion -direkt oder indirekt- aufrufen.

Haeufig werden a0/a1 aber auch als Parameter eben dieser Systemfunktionen
verwendet, und da ist es nicht unwichtig zu wissen, ob das Tagarray
bereits relativ zu a1 aufgebaut werden soll oder net, so als Gedanken-
experiment, belegen kann ich das dank mangelnder Erfahrung mit was
anderm als exec und dos nicht ;-))

> - Die Werte werden auf dem Stack uebergeben, und da _bleiben_
> sie dann auch, weil der Stack damit zum TagArray _wird_.

De Fakto, weiss das der Compiler? (Wieder meine Hints...)

> Was gewinnt man durch die automatic-Deklaration von Strings?
>Ein _builtin_strcpy() vom (in diesem Falle dann _doch_ wieder statisch
>initialisierten) DATA-Segment auf den Stack? Doppelter Speicherbedarf,

Hierzu siehe auch meine vorherige Mail. Nur ein Hinweis: Strings zwischen
Anfuehrungszeichen sind Konstanten. Konstanten haben meiner Ansicht nach
nichts, aber auch rein gar nichts in einem DATA Segment verloren,
das veraenderliche Daten beherbergen soll (und dessen Groesse bei a4-
relativer Adressierung ja beschraenkt ist!).

>ideale Ansatzpunkt fuer Optimierungen], ansonsten erzeugen Funktionsaufrufe
>aber regelmaessig _kuerzeren_ Code. Keine Frage "K&R vs. ANSI" sondern ganz
>einfach "Effizienz vs. Komfort"!

Womit wir die ganze Zeit ueber Optimierung an sich sprachen, und gar nicht
definiert haben, *was* wir denn optimieren wollen. In der Regel will ich
persoenlich schnellen Code, und wenn er dann auch noch kurz ist, noch
besser. In genau dieser Reihenfolge. Das heisst, ich finde automatisches
Loop-unrolling in gewissen Faellen, wo's angebracht ist, aeusserst
angenehm, auch wenn der Code dadurch laenger wird. Aehnlich gelagertes
Feature: kleine Funktionen automatisch inline zu expandieren
(-finline-functions) kann einen significanten Geschwindigkeitsvorteil
bedeuten, auch wenn dadurch logischerweise die Codegroesse waechst.

>> Es ist doch durchaus huebsch, mktemp(3) so
>> zu implementieren:
>> char template[] = "ram:t/tmpl.XXXXXX";
>
> "Huebsch" ist eine subjektive Empfindung. Tatsache ist, dass
>im fertigen Objektmodul sowohl der initiale Stringinhalt im DATA-
>Segment steht, zum Funktionseintritt als erstes von dort auf den
>Stack _umkopiert_ wird, um dann gleich wieder in subsequenten
>Konstrukten _ueberschrieben_ zu werden. Da bleibt die Effizienz doch
>irgendwo auf der Strecke, findest Du nicht? Selbst unter der Annahme,

Also.. der Initialisierungs-String besteht hier dynamisch aus 2
Teilen, erstens dem ersten Teil des Filenamens, den alle erzeugten
eindeutigen Filenamen gemein haben. Der zweite Teil ist eine Art
Maske, die die Funktion ausfuellen soll, um aus dem Filenamen als
ganzes was eindeutiges zu erzeugen. Obwohl die X'e also ueberschrieben
werden, erfuellen sie eine Funktion.

>> [...] Die ANSI-Variante sieht nicht
>> nur schoener aus, sondern ist auch einfacher zu verwenden, IMHO ;-)
>
> Die Frage lautet halt immer: "Wieviel Bytes ist Dir
>Deine Faulheit wert" :-) :-).

>--
>Best regards,
>Franz-Josef Reichert GERMANY - VOICE: +49 6805 7417
>Kuchlingerstrasse 13 UUCP: fjrei@kbsaar.{saar|adsp}.sub.org
>6601 Kleinblittersdorf fj...@kbsaar.saar.de

Noe.. denn um das Entsprechende `traditional' zu schreiben, wird
die Funktion entweder zu einem Fall-typischen Riesenhack (abzaehlen,
wo die einzelnen Teil-Bereiche im Template beginnen), oder Du landest bei

char template[sizeof ("ram:t/tmpl.XXXXXX")];

...
strcpy (template, "ram:t/tmpl.XXXXXX");

Was eben in meinen Augen weniger huebsch aussieht, und im Endeffekt
aber ziemlich sicher gleichviel Code erzeugen wird.

-Markus


--

Franz-Josef Reichert

unread,
Jul 2, 1992, 9:42:53 PM7/2/92
to
In article <1992Jul2.1...@bernina.ethz.ch>, Markus Wild writes:

> Beispiel fuer das Gegenteil sind C++ Constructors, die globale Daten
> initialisieren sollen. Da spricht doch niemand von `Wertbestimmung' oder
> aehnlichem...

Nana, C++ gilt aber nicht! Hier geht's doch um C!

> > Statisch = i.S.v. Wertbestimmung _vor_ der Laufzeit.
> i.S.v. gleich "im Schweisse von" oder was?

"im Sinne von"

> Ich moechte einfach vermeiden, dass wir hier Aepfel mit Birnen vergleichen.
> Entweder Deine Strings sind konstant, dann wird `man' Pointers
> verwenden. Sind Deine Strings nicht konstant, kommst Du um die Arrays

> nicht rum [...]

Beides aendert aber nichts am Ergebnis: Ich erhalte
statische Daten (= die initialen Stringinhalte) im Lademodul. Ob die
Strings nun ueber Pointer oder Arraynamen (wo soll da eigentlich ein
Unterschied sein?) referenziert werden, ist doch wohl belanglos (bis
auf den eher feinen Unterschied, dass ich fuer den Pointer noch vier
Bytes extra benoetige, was aber hier nicht weiter interessiert).

> Dass man fuer Array-Initialisierung '=' verwendet, und nicht
> strcpy(), muesste doch klar sein, oder?

Sicher. Nur erzeugt die Initialisierung eines
'automatic' angelegten Arrays mit '=' numal ein implizites
strcpy(), ohne Verzicht auf eine statische Kopie der initialen
Daten. Wo kaemen sie sonst her? Von der Idee, Stringinhalte
inline zu codieren, muss ja sinnvollerweise ab einigen wenigen
Zeichen aufwaerts abgesehen werden. "bar\0" ist aber gut, das
passt prima in's Langwort rein :-).

--

Franz-Josef Reichert

unread,
Jul 2, 1992, 7:38:39 PM7/2/92
to
In article <1992Jul2.1...@bernina.ethz.ch>, Markus Wild writes:
> Nuja, also mal davon ausgehend, dass uns der Varargs-Support von
> amiga.lib beschert wurde, und nicht ein offizieller Einsprung in die
> Library ist, finde ich eine Implementation mit Tag Arrays schoener.

Ja, moeglicherweise "schoener"! Aber damit auch besser?
Besser wird's in meinen Augen erst dann, wenn es entweder kuerzer,
schneller oder beides wird.

> > Was ist "schade"? Beschreibe doch mal bitte, was diese
> >"Inline expansion", was immer damit gemeint sei, in diesem Zusammenhang
>
> Kleines Beispiel gefaellig?
>
> #define va_expand(valist) valist##,
> #define AllocAslRequestTags(type, tags...) \
> ({ ULONG _tags[] = { va_expand(tags) TAG_DONE,0 }; \
> AllocAslRequest (type, (struct TagItem *) _tags); })

Ja, schoen! Aber was passiert denn jetzt? Jetzt faengt
doch der Compiler an, zu jedem Aufruf von AllocAslRequestTags()
ein huebsches kleines TagArray (bestenfalls) auf dem Stack anzulegen,
oder? Also etliche "move.l value,dx / move.l dx,-(a0)" oder so aehnlich,
um dann irgendwann die eigentliche Funktion aufzurufen. Unterscheidet
sich das wesentlich von dem, was man ueber den Varargs-Stub macht? Wohl
nicht!

Im Falle von lauter _konstanten_ Tags waere es doch effizient,
dieses Konstrukt _nicht_ zu verwenden. Denn dann waere ja

lea.l tagarray(a4),a0

guenstiger. Ein Grenzfall, also gut. Nun aber der weitaus
haeufigere Fall, die Menge der zu uebergebenden Tags setze sich aus
einem Anteil konstanter und dynamisch zu bestimmender zusammen.
Wenigstens fuer den konstanten Anteil koennte man sich die dynamische
(mit Codegenerierung verbundene) Erzeugung eines TagArrays auf dem
Stack sparen, wenn man die Werte bereits statisch im Lademodul haette
und in eine (unausweichliche) Varargs-Uebergabe der dynamischen Tags
ueber TAG_MORE einbauen koennte. Damit spart man doch fuer jeden konstanten
TagItem zumindest zweimal das Erzeugen von Werten (TagID und TagValue)
sowie das Schieben dieser in ein zur Laufzeit erzeugtes TagArray (s.o.).
Und das ist doch zweifelsohne schon _besser_ als o.a. Konstrukt, was in
diesem Fall _redundanten_ Code erzeugt! Klar, komfortabler ist das schon,
man muss halt weniger ueberlegen und kann schneller mal was aendern.

Was mich an obigem Konstrukt stoert, ist dass es nicht
das "Fachwissen" beinhaltet, ein TagArray in einen konstanten
und dynamischen Anteil zu zerlegen. Und dass 'C' keine syntaktischen
Moeglichkeiten bietet, dieses Fachwissen "reinzuzwaengen". Und dass man
folglich mit Verwendung dieses Konstruktes Fachwissen ueber Bord wirft.

Noch ein Aspekt: Moeglicherweise koennte der konstante
Teil des TagArrays mehrfach im gleichen Programm verwendet werden.
Inwieweit beruecksichtigt Dein Loesungsvorschlag diesen Fall?

> Wir sind in erster Linie von dynamischen (!) Tags ausgegangen, nicht
> von statischen Tabellen, fuer die's ja absolut keinen Sinn macht,
> sie umzukopieren.

Das ist trivial! Rein statische oder rein dynamische
TagArrays interessieren nicht. Oben zeigte ich, dass _rein_ dynamische
TagArrays nur solange Sinn machen, wie sie nicht _wenigstens_ eine
Konstante enthalten und umgekehrt! Brisant ist eben die Mischung!

> > Redundanzen koennen nie zu mehr als 100% entfernt werden.
> >Also der gleiche Effekt, als wenn man sie erst gar nicht erzeugt
>
> Du gehst davon aus, dass genau eine Loesung existiert, aus gegebener
> Source Assembly zu erstellen. Dem ist aber in der Regel nicht so.

Wenn man sich in der Wahl der Loesungsmoeglichkeiten auf
_optimale_ Loesungen beschraenkt, ist dagegen wohl nichts einzuwenden.
Natuerlich kann jedes Problem mehrere Loesungen haben; ich will aber
nicht _irgendeine_ Loesung, ich will eine _optimale_ Loesung! :-)

> In gewissen
> Faellen kann eine andere Datensammlung, die Du dem Compiler zum
> Verarbeiten auf den Weg gibst, zu einem total anderem Resultat fuehren.

Womit nur bewiesen ist, dass Compiler nicht perfekt sind :-).

> > - Die Werte werden auf dem Stack uebergeben, und da _bleiben_
> > sie dann auch, weil der Stack damit zum TagArray _wird_.
>
> De Fakto, weiss das der Compiler? (Wieder meine Hints...)

Ja, also das weiss er nun wirklich mal ohne fremde Hilfe.
Solange ich keine Funktionsprototypen mit Registerparametrisierung
verwende, wird er wohl nie auf eine andere Idee kommen, als Parameter
auf dem Stack abzulegen. Hints sind rudimentaere Vereinfachungen davon,
was ich oben mit "Fachwissen" bezeichne; leider nicht "allmaechtig",
was sie im begrenzten Rahmen der Sprache auch niemals sein koennten.

> Hierzu siehe auch meine vorherige Mail. Nur ein Hinweis: Strings zwischen
> Anfuehrungszeichen sind Konstanten. Konstanten haben meiner Ansicht nach
> nichts, aber auch rein gar nichts in einem DATA Segment verloren,

Das ist nicht das Problem. Man kann Konstanten auch in's
Code-Segment packen lassen (der SAS/C macht das wohl auch). Aber
das geht eben nur, wenn man's _statisch_ macht. Auf dynamischer
Ebene kann doch nicht mehr unterschieden werden, ob ein Wert fuer's
TagArray eine konstante oder variable Groesse repraesentiert! Das ist
ja gerade der Ansatzpunkt meiner Kritik! Ich find's halt nicht so
toll, wenn ich ein "moveq #10,d0 / move.l d0,-(a0)" generiere, wo
immer ich diese Zehn (oder jeden anderen konstanten Wert) ueber
einen Pointer auf statischen Speicher -ob im Daten- oder Codesegment
spielt in diesem Fall ueberhaupt keine Rolle- referenzieren _koennte_.
Die zwei move's kosten mich doch garantiert mehr _Speicher_ und
_Rechenzeit_, als die andere Loesung verschlingt. Die kommt naemlich
gaenzlich _ohne_ Code aus.

> Womit wir die ganze Zeit ueber Optimierung an sich sprachen, und gar nicht
> definiert haben, *was* wir denn optimieren wollen.

Die Frage ist fuer diesen Fall doch recht einfach zu beantworten.
Als gaengige Loesungen fuer dieses Problem existieren statisches, dynamisches
oder gemischtes Anlegen eines TagArrays. Zu finden ist eine Loesung, die
ceteris paribus entweder weniger Rechenzeit und/oder weniger Speicher
braucht.

> char template[sizeof ("ram:t/tmpl.XXXXXX")];

> strcpy (template, "ram:t/tmpl.XXXXXX");
>
> Was eben in meinen Augen weniger huebsch aussieht, und im Endeffekt
> aber ziemlich sicher gleichviel Code erzeugen wird.

(Naja, mit #define TMPLSTR "ram:t/tmpl.XXXXXX" vielleicht noch zu
verschoenern)

So muesste man es machen. Allerdings stimmt "gleichviel" nicht.
Eher muesste es heissen "gleichviel oder weniger". Weniger naemlich genau
dann, wenn strcpy() noch mindestens einmal im gleichen Programm gebraucht
wuerde und daher nicht inline, sondern als Funktionsaufruf implementiert
waere. Allerdings haette ich _den_ Compiler noch zu sehen, der ein aus
automatic-Stringdeklarationen resultierendes inline-strcpy in einen
Funktionsaufruf umzuwandeln verstuende :-).

[Die paar Zyklen, die ein inline-strcpy weniger gegenueber
dem Funktionsaufruf benoetigt, musst Du mir jetzt aber schenken! Du hast
naemlich oben nur weniger Code_laenge_ gefordert! :-) :-)]

--

Gerald Malitz

unread,
Jun 30, 1992, 4:52:26 PM6/30/92
to
In article <JcBgr*r...@zikzak.in-berlin.de>, Andreas M. Kirchwitz writes:

> PS: Ersetz den String durch TagItems oder sonstwas...
> Die Warning bleibt. Das Programm laeuft auf den ersten Blick normal.
> GIB WARNINGS KEINE CHANCE!

Ich bleibe dabei, ignorier sie!

> PPS: Kann man beim BLink eigentlich bestimmte Warnings (ausser mit "grep")
> unterdruecken?

Nicht, dass ich wuesste: karg, kaerger, am kaergsten, Doku zu
Blink :( Es ist ja nicht einmal dokumentiert, dass Blink ueberhaupt
Warnings ausgibt. Jedefalls habe ich im SAS-Manual nichts gefunden.
Kennt jemand sonst noch irgendwas?

> PPPS: Interessante Effekte erhaelt man, wenn man 'printf("%s",text);'
> durch 'printf(text);' ersetzt. Eindrucksvoller Memory-Dump...
> Anscheinend ist die Warning eine warnende Warning, der man doch
> besser Beachtung schenken sollte.

Welche Version von Blink benutzt Du? Mein Blink 5.10b
produziert in dem Fall ein File, das gar nicht executable ist :(.
Jedenfalls darfst Du die Option SD oder SMALLDATA nicht benutzen.
Das haengt mit den initialisierten auto-Arrays zusammen, ist aber
doch nicht deren Schuld. Bitte mich jetzt bitte nicht, das zu
erklaeren :)

Tschuess, Gerald.

Gerald Malitz

unread,
Jul 4, 1992, 8:12:56 AM7/4/92
to
In article <1992Jun30.2...@bernina.ethz.ch>, Markus Wild writes:

> In article <JcBgr*r...@zikzak.in-berlin.de> a...@zikzak.in-berlin.de (Andreas M. Kirchwitz) writes:
>
> > "Warning! Absolute reference to UNKNOWN" ... Andreas
>
> Hat vermutlich damit zu tun, dass SAS String-Konstanten grundlos in den
> DATA Hunk wirft, und damit zu veraenderlichen Objekten erklaert. Wenn
> die String-Konstante "Hello World\n" (und nicht etwa text!) im CODE Hunk
> waere, haette BLink gar nix zu motzen, denn dann haette er keine data-text
> Relokation auszufuehren, die ja in einem resident-faehigen Programm nicht
> auftreten sollte.

Strings haben im Code-Hunk nichts zu suchen, denn sie sind
ja nun mal nicht executable. Veraenderlich - im Sinne von nicht vor
Schreibzugriffen geschuetzt - sind sie beim Amiga ja in jedem Fall, Exec
bietet kein Protected-Memory. Andererseits kann ein Programm mehrere
Data-Hunks haben, die wiederum jeweils verschiedene Attribute haben
koennen. Als Attribute bietet Exec z. B. MEMF_CHIP oder MEMF_FAST,
sobald es eines gibt, das vor Schreibzugriffen schuetzt, waere das
die erste Wahl. (Btw. wer seine Strings nun doch unbedingt unter den
Code gemixt haben will, soll sich aus dem Handbuch eine geeignete
Compileroption suchen. Die gibt es naemlich auch. Aetsch. Helfen
wuerde es in diesem Fall aber auch nicht.)

> -Markus

Olaf Barthel

unread,
Jul 4, 1992, 1:30:28 PM7/4/92
to
In article <JcBgr*r...@zikzak.in-berlin.de> a...@zikzak.in-berlin.de (Andreas M. Kirchwitz) writes:
>#include <stdio.h>
>#include <stdlib.h>
>
>int main(int argc, char *argv[])
>{
> char text[] = "Hello World\n";
> printf("%s",text);
> exit(10);
>}
>
>Optionen: <keine>
>Compiler: lc test.c
>Linker : blink FROM LIB:cres.o test.o TO test LIB LIB:lc.lib SD SC ND
>
> "Warning! Absolute reference to UNKNOWN" ... Andreas
>
>PS: Ersetz den String durch TagItems oder sonstwas...
> Die Warning bleibt. Das Programm laeuft auf den ersten Blick normal.
> GIB WARNINGS KEINE CHANCE!
> (wollte damit eigentlich nur demonstrieren, dass das Problem nichts
> speziell mit TagItems oder der reqtools.lib zu tun hat ;-)

Ich komme der Sache naeher, das Problem haengt meiner Meinung nach mit
der aggregate-initialization zusammen. Das Objekt, das Du gerne erzeugen
wuerdest, wird erst zur Laufzeit erstellt, aber offenbar verschluckt sich
der Compiler bei dem Versuch, die statischen Daten, mit denen das Objekt
initialisiert werden soll, korrekt im Speicher unterzubringen. Du kannst
den Ort des Problems uebrigens wunderbar lokalisieren, wenn Du

LC -L -tr -D test.c

eingibst. Allerdings funktioniert hingegen alles wunderbar, wenn der
Programmtext folgendermassen aussieht:

int main(int argc, char *argv[])
{

char *text = "Hello World\n";
printf("%s",text);
exit(10);
}

Der Compiler hat sich hier nicht mit der Initialisierung eines Arrays
herumzuschlagen, sondern kann gleich eine Referenz auf statisch
initialisierte Daten verwenden. Probleme gibt es natuerlich dadurch,
dass Du nicht mehr unbedingt darueber informiert wirst, wie umfangreich
das Array denn nun wirklich ist und kannst auch nicht festlegen, dass es
eine bestimmte Laenge, die groesser als der String sein kann, haben
soll. Ich vermute allerdings, dass Du dergleichen fuer Deine TagItem-Lists
ohnehin nicht benoetigen wirst.

Ich halte das sich hier manifestierende Problem fuer einen echten
Compiler-Bug.

>IRC-Nick: | Andreas M. Kirchwitz, Seesener Str. 69, W-1000 Berlin 31, Germany
> `bonzo' | Phone: +49 (0)30 873376, Mail: amk@{zikzak.in|cs.tu|fu}-berlin.de

--

Markus Wild

unread,
Jul 5, 1992, 10:04:59 AM7/5/92
to
In article <Ebnir*P...@germal.bs.open.de> g...@germal.bs.open.de (Gerald Malitz) writes:
> Strings haben im Code-Hunk nichts zu suchen, denn sie sind
>ja nun mal nicht executable. Veraenderlich - im Sinne von nicht vor
>Schreibzugriffen geschuetzt - sind sie beim Amiga ja in jedem Fall, Exec
>bietet kein Protected-Memory. Andererseits kann ein Programm mehrere

Diese Unterscheidung ist ja nur wichtig, wenn Du residentfaehige Programme
schreiben willst, deshalb hab ich das ja explit erwaehnt. In diesem Falle
kannst Du Dir nicht mehrere Data-Hunks leisten, da Du ja mit A4 alle DATA
Objekte erreichen musst. Chip-Data Hunks sind unter diesen Umstaenden auch
speziell, und muessen wie CODE Hunks behandelt werden, denn wenn sie auch
veraenderlich sind, hast Du im Nu ein nicht-pures Programm.

>die erste Wahl. (Btw. wer seine Strings nun doch unbedingt unter den
>Code gemixt haben will, soll sich aus dem Handbuch eine geeignete
>Compileroption suchen. Die gibt es naemlich auch. Aetsch. Helfen
>wuerde es in diesem Fall aber auch nicht.)

Aeh, wer sagt denn, dass Exec *nie* Protected Memory bieten wird?
Genauso wenig wie es Protected Memory gibt im Moment, gibt's Protected
Hunks, also steht's 1:1, aetsch zurueck;-))) Helfen tut es immer dann,
wenn residentfaehige Programme mit moeglichst viel Data erzeugt werden
sollen.

Martin Horneffer

unread,
Jul 7, 1992, 4:12:50 AM7/7/92
to
fj...@kbsaar.saar.sub.org (Franz-Josef Reichert) writes:

> Was gewinnt man durch die automatic-Deklaration von Strings?
>Ein _builtin_strcpy() vom (in diesem Falle dann _doch_ wieder statisch
>initialisierten) DATA-Segment auf den Stack? Doppelter Speicherbedarf,
>zusaetzlicher Code!

Nun bin ich aber gespannt: was war denn am angegebenen Beispiel unnoetiger
Speicherbedarf oder Code, was war daran uneffizient oder unschoen?

Wie sollte man es besser machen, wenn man nunmal einen vorgegebenen String
in mehreren zur Laufzeit erzuegten Variationen braucht?

>irgendwo auf der Strecke, findest Du nicht? Selbst unter der Annahme,
>dass der erste Schritt "wegoptimiert" wird (der Compiler finde irgendwie
>(?) heraus, dass der initiale Inhalt von template[] nicht benoetigt werde),
>gewinnt man mit dieser Moeglichkeit unterm Strich _nichts_.

Man verliert aber auch nichts, es ist huebscher und man ist auf der
sicheren Seite, wenn man solche Strings mal aendert und mal nicht.

> Die Frage lautet halt immer: "Wieviel Bytes ist Dir
>Deine Faulheit wert" :-) :-).

Ich sehe in solchen Sachen ausserdem weniger eine Sache der Faulheit,
sondern des Lesbarkeit, Uebersichtlichkeit, damit Wartbarkeit sowie v.a
der Sicherheit.

*Dein* Verstaendnis von C scheint mir Wirth's Spruch ueber C als "mit Syntax
verzuckerter Assembler" nur zu bestaetigen (so wenig er auch in anderen
Faellen gerechtfertigt sein mag).

Gruss, Martin
--
Martin Horneffer - ma...@dfv.rwth-aachen.de;
Fido: 2:242/7.9; Martin_H...@mowgli.fido.de;
Maus: AC, AC2; Martin_H...@ac.maus.de

Gerald Malitz

unread,
Jul 5, 1992, 6:49:37 AM7/5/92
to
In article <TGlhr*2...@kbsaar.saar.sub.org>, Franz-Josef Reichert writes:

> - Die Werte werden auf dem Stack uebergeben, und da _bleiben_
> sie dann auch, weil der Stack damit zum TagArray _wird_.
>
> - 'automatic'-Variablen werden gemeinhin _auch_ nirgendwo
> anders als auf dem Stack instantiiert. Jede Abweichung
> hiervon erzeugt _nochmals_ zusaetzlichen Code zur Speicher-
> beschaffung, Verwaltung und abschliessender Freigabe.
>
> - Die Schlussfolgerung ist in diesem Zusammenhang falsch.

[...]


> Was gewinnt man durch die automatic-Deklaration von Strings?
> Ein _builtin_strcpy() vom (in diesem Falle dann _doch_ wieder statisch
> initialisierten) DATA-Segment auf den Stack? Doppelter Speicherbedarf,
> zusaetzlicher Code! (Womit nicht gesagt sein soll, dass es fuer diesen
> Mehraufwand niemals eine Rechtfertigung geben mag). Ich bin nur sehr
> vorsichtig mit "Segnungen" dieser Art. Wer zeitkritische Applikationen
> schreibt, mag hunderte von builtin-Funktionen und damit verbundene
> Codegenerierung erdulden [nur am Rande: strcpy() ist m.E. _selten_ der
> ideale Ansatzpunkt fuer Optimierungen], ansonsten erzeugen Funktionsaufrufe
> aber regelmaessig _kuerzeren_ Code. Keine Frage "K&R vs. ANSI" sondern ganz
> einfach "Effizienz vs. Komfort"!

Blah, blubber, baleh! Hast Du Dir eigentlich mal angesehen,
was wirklich passiert, bevor Du diese Schwallung losgelassen hast?
>:^} Harr, harr, kling, kling (Ach, das verstehen die Sueddeutschen
ja wieder nicht =B^) ).

Um mal bei den TagItems zu bleiben: Mit dem auto-Array hast
Du am Anfang der Funktion (dort, wo das Array definiert wird) Code, der
das Array auf den Stack kopiert (je nach Arraygroesse als Schleife oder
ein paar Moves) und Du hast das Original des TagArrays. Wenn Du die
Varargs-Version benutzt, generiert der Compiler eine Latte von PEAs
(o.ae.) vor jedem Aufruf der Funktion, die die Tags bekommt. Nur fuer
sehr kleine TagArrays braucht das wirklich weniger Platz (da sind noch
zwei LEAs, um die die auto-Version unguenstiger ist) und es ist nur
minimal schneller (eigentlich nur um das fehlende DBRA). Sollte es
sich ergeben, dass dasselbe TagArray innerhalb der Funktion mehr als
einmal fuer einen Funktionsaufruf benutzt wird, hat die Varargs-Version
endgueltig verloren. Aetschbaetsch!

Praktisch sieht das so aus:

; int fooa(char *, struct TagItem *);
; int foo(char *, Tag, ...);
;
; void bar(void) {
LINK A5,#FFE0 ; Hiermit wird der Platz auf dem Stack belegt
; struct TagItem tags[] = { 5, NULL, 6, NULL, 7, NULL, TAG_END };
LEA 02.00000000,A0 ; Die Adresse der Originaldaten, ...
LEA FFE0(A5),A1 ; die Adresse des Arrays auf dem Stack ...
MOVEQ #07,D0 ; und kopieren
MOVE.L (A0)+,(A1)+
DBF D0,0010
;
; fooa("baz", tags);
PEA FFE0(A5) ; Wenn man pragmas benutzt sieht das natuerlich
PEA 01.00000000(A4) ; etwas anders aus: LEA nach ax statt PEA, ein
BSR.W _fooa ; MOVE libbase nach a6 dazu, dann JSR xxx(a6)
; fooa("babbel", tags);
PEA FFE0(A5)
PEA 01.00000004(A4)
BSR.W _fooa
; foo("baz", 5, NULL, 6, NULL, 7, NULL, TAG_END);
MOVEQ #00,D0 ; Viel elendes Geraffel ...
MOVE.L D0,(A7)
MOVE.L D0,-(A7)
PEA 0007
MOVE.L D0,-(A7)
PEA 0006
MOVE.L D0,-(A7)
PEA 0005
PEA 01.0000000C(A4)
BSR.W _foo ; und noch immer nicht die Funktion, nur'n Stub
; /* foo("babbel", 5, NULL, 6, NULL, 7, NULL, TAG_END); spar ich mir jetzt :^) */
; }
UNLK A5
RTS

Dazu kommen dann noch die Schwierigkeiten, die Du mit dem Stub
hast, wenn die libbase keine globale Variable ist, sondern z. B. eine
lokale der Funktion bar, ein Element einer Struktur oder sonstwas.

Gerald Malitz

unread,
Jul 7, 1992, 5:08:59 AM7/7/92
to
In article <olsen...@sourcery.mxm.sub.org>, Olaf Barthel writes:

> Ich komme der Sache naeher, das Problem haengt meiner Meinung nach mit
> der aggregate-initialization zusammen. Das Objekt, das Du gerne erzeugen
> wuerdest, wird erst zur Laufzeit erstellt, aber offenbar verschluckt sich
> der Compiler bei dem Versuch, die statischen Daten, mit denen das Objekt
> initialisiert werden soll, korrekt im Speicher unterzubringen.

Kaaalt, gaaanz kaaalt...

> Ich halte das sich hier manifestierende Problem fuer einen echten
> Compiler-Bug.

Sorry, but no cigar. Actually not even close..

Gerald Malitz

unread,
Jul 9, 1992, 4:07:59 AM7/9/92
to
In article <1992Jul5....@bernina.ethz.ch>, Markus Wild writes:

> In article <Ebnir*P...@germal.bs.open.de> g...@germal.bs.open.de (Gerald Malitz) writes:
> > Strings haben im Code-Hunk nichts zu suchen, denn sie sind
> >ja nun mal nicht executable. Veraenderlich - im Sinne von nicht vor
> >Schreibzugriffen geschuetzt - sind sie beim Amiga ja in jedem Fall, Exec
> >bietet kein Protected-Memory. Andererseits kann ein Programm mehrere
>
> Diese Unterscheidung ist ja nur wichtig, wenn Du residentfaehige Programme
> schreiben willst, deshalb hab ich das ja explit erwaehnt. In diesem Falle
> kannst Du Dir nicht mehrere Data-Hunks leisten, da Du ja mit A4 alle DATA
> Objekte erreichen musst. Chip-Data Hunks sind unter diesen Umstaenden auch
> speziell, und muessen wie CODE Hunks behandelt werden, denn wenn sie auch
> veraenderlich sind, hast Du im Nu ein nicht-pures Programm.

Natuerlich koennen residentfaehige Programme mehrere Data-Hunks
haben, und sie haben sie auch. Lediglich die globalen veraenderlichen
Daten muessen relativ adressiert werden. Die Konstanten - um genau die
geht es ja - koennen ebenso wie der Code gemeinsam benutzt werden. Sie
werden in jedem Fall absolut adressiert, ob sie nun in einem Code oder
einem Datensegment liegen. Wenn Du das Beispielprogramm von Andreas mal
compilierst, hast Du (zumindest mit SAS) ein Executable mit drei Hunks:
dem Code-Hunk und zwei Daten-Hunks, einer enthaelt die globalen Variablen
des Programms (in dem Fall hauptsaechlich aus der Linklibrary), der andere
die Konstanten (in dem Fall den String "Hello World\n"). Letzterer muss
eben nicht in den Code-Hunk.

Deshalb bekommt Andreas ja auch Probleme, wenn er dem Linker
die Option SMALLDATA mitgibt. Dann werden diese beiden Data-Hunks
zusammengefasst. Wenn er Pech hat, landet am Ende alles - auch die
Variablen - im Hunk fuer globale Konstanten. Klar, dass das schief
geht.

> >die erste Wahl. (Btw. wer seine Strings nun doch unbedingt unter den
> >Code gemixt haben will, soll sich aus dem Handbuch eine geeignete
> >Compileroption suchen. Die gibt es naemlich auch. Aetsch. Helfen
> >wuerde es in diesem Fall aber auch nicht.)
>
> Aeh, wer sagt denn, dass Exec *nie* Protected Memory bieten wird?

Und wovon traeumst Du Nachts ;^)

> Genauso wenig wie es Protected Memory gibt im Moment, gibt's Protected
> Hunks, also steht's 1:1, aetsch zurueck;-)))

Abseits, ganz klar! =:^> Dir fehlt nach wie vor der Grund,
Daten in den Code zu mischen - da sie ja so oder so nicht geschuetzt
sind und in jedem Falle absolut% adressiert werden muessen.

% mindestens aber pc-relativ, das ist aber auch nicht ohne,
da bei SAS die Module auf 64K beschraenkt sind.

> Helfen tut es immer dann,
> wenn residentfaehige Programme mit moeglichst viel Data erzeugt werden
> sollen.

Helfen kann ich nur dann, wenn Konstanten da sind, die aus
dem relativ zu a4 adressierten Bereich herausgenommen werden koennen.
Die muss ich aber nicht in ein Code-Segment packen, sondern kann sie -
wie oben beschrieben - auch in einem eigenen Daten-Segment unterbringen.

Nebenbei: das Erzeugen residenter Progamme mit cres.o ist IMHO
sowieso nur ein Hack, fuer den man einen Preis zahlt. Die globalen
Variablen sind auf 64K beschraenkt (schoenen Gruss an die DOSe), das
ganze fuehrt leicht zu Verwirrungen (Blink-Warnings) oder Abstuerzen
(Option SMALLDATA) und __saveds bzw. geta4() tun auch nicht mehr wie
gewuenscht.

Markus Wild

unread,
Jul 10, 1992, 10:46:08 AM7/10/92
to
In article <vQ+jr*y...@germal.bs.open.de> g...@germal.bs.open.de (Gerald Malitz) writes:
>einem Datensegment liegen. Wenn Du das Beispielprogramm von Andreas mal
>compilierst, hast Du (zumindest mit SAS) ein Executable mit drei Hunks:
>dem Code-Hunk und zwei Daten-Hunks, einer enthaelt die globalen Variablen

Grusel... Hunk'itis...

>zusammengefasst. Wenn er Pech hat, landet am Ende alles - auch die
>Variablen - im Hunk fuer globale Konstanten. Klar, dass das schief
>geht.

Tolles System, muss ich sagen... wirklich durchdacht ;-)

> Abseits, ganz klar! =:^> Dir fehlt nach wie vor der Grund,
>Daten in den Code zu mischen - da sie ja so oder so nicht geschuetzt
>sind und in jedem Falle absolut% adressiert werden muessen.

Ich bin fuer `so wenig Hunks wie moeglich', sonst frustets mich
wieder wenn die HD-LED beginnt zu blinken, anstelle schoen brav
zu leuchten, wenn ich ein Proggy lade... Daher, mehrere Datenhunks
sind grusel ;-)

> Helfen kann ich nur dann, wenn Konstanten da sind, die aus
>dem relativ zu a4 adressierten Bereich herausgenommen werden koennen.

Was grundsaetzlich String-Konstanten und alles, was `const'
deklariert ist, sein kann.

> Nebenbei: das Erzeugen residenter Progamme mit cres.o ist IMHO
>sowieso nur ein Hack, fuer den man einen Preis zahlt. Die globalen
>Variablen sind auf 64K beschraenkt (schoenen Gruss an die DOSe), das
>ganze fuehrt leicht zu Verwirrungen (Blink-Warnings) oder Abstuerzen
>(Option SMALLDATA) und __saveds bzw. geta4() tun auch nicht mehr wie
>gewuenscht.

gcc, sowohl cc1 als auch cc1plus sind a4-relativ gelinkt!! Da kannst
Du sowohl pc-relative Text-Adressierung, als auch jegliche Ver-
schwendung von Data-Space abschreiben. Bei cc1plus werden ca 50k
Daten benoetigt, mit all den Texten im Datenteil koennte man's glatt
vergessen. A4-laden geht mit gcc und ixemul.library uebrigens auch
in residenten Programmen, re-aetsch ;-)

Gerald Malitz

unread,
Jul 11, 1992, 6:15:51 PM7/11/92
to
In article <1992Jul10....@bernina.ethz.ch>, Markus Wild writes:

> In article <vQ+jr*y...@germal.bs.open.de> g...@germal.bs.open.de (Gerald Malitz) writes:
> >einem Datensegment liegen. Wenn Du das Beispielprogramm von Andreas mal
> >compilierst, hast Du (zumindest mit SAS) ein Executable mit drei Hunks:
> >dem Code-Hunk und zwei Daten-Hunks, einer enthaelt die globalen Variablen
>
> Grusel... Hunk'itis...

Keine Panik! Drei Hunks sind noch kein Fall fuer den Pathologen...

> >zusammengefasst. Wenn er Pech hat, landet am Ende alles - auch die
> >Variablen - im Hunk fuer globale Konstanten. Klar, dass das schief
> >geht.
>
> Tolles System, muss ich sagen... wirklich durchdacht ;-)

Hmm, naja, sehr schick ist das nicht. Aber sowas kann
vorkommen, wenn jemand mit Optionen spielt, deren Bedeutung er
nicht durchschaut =;^>

> > Abseits, ganz klar! =:^> Dir fehlt nach wie vor der Grund,
> >Daten in den Code zu mischen - da sie ja so oder so nicht geschuetzt
> >sind und in jedem Falle absolut% adressiert werden muessen.
>
> Ich bin fuer `so wenig Hunks wie moeglich', sonst frustets mich
> wieder wenn die HD-LED beginnt zu blinken, anstelle schoen brav
> zu leuchten, wenn ich ein Proggy lade... Daher, mehrere Datenhunks
> sind grusel ;-)

Hey, ANU! Amigas Not Unix! Hier hat nicht jeder seinen
eigenen, privaten Adressraum. Mit der Zahl der Hunks steigen die
Chancen, dass sich ein Programm noch in den fragmentierten
Speicher zwaengen kann. Oder sei's auch nur, dass angeknabberter
Speicher besser ausgenutzt wird.

Ist das mit der Ladezeit den so gravierend? Ist mir noch
nicht aufgefallen, aber ich muss mit meinem System ja sowieso 'ne
Menge Geduld haben. Auf jeden Fall dauert es laenger, wenn ich
erst nochmal booten muss, bevor gcc laeuft... :^)

> A4-laden geht mit gcc und ixemul.library uebrigens auch
> in residenten Programmen, re-aetsch ;-)

Auch bei Interrupt-Funktionen? Nicht, dass es nicht ginge,
aber... Ich vermeide es sowieso, globale Daten aus Interrupts zu
veraendern, und ziehe is_Data vor.

> -Markus

Tschuess, Gerald.

--
// Gerald Malitz, Bolchentwete 4, 3300 Braunschweig, Voice: +49 531 796832

\X/ g...@germal.bs.open.de "Hoop diddy diddy - Hoop diddy do" Queen

Markus Wild

unread,
Jul 12, 1992, 10:15:44 AM7/12/92
to
In article <TGPkr*K...@germal.bs.open.de> g...@germal.bs.open.de (Gerald Malitz) writes:
>> Ich bin fuer `so wenig Hunks wie moeglich', sonst frustets mich
>> wieder wenn die HD-LED beginnt zu blinken, anstelle schoen brav
>> zu leuchten, wenn ich ein Proggy lade... Daher, mehrere Datenhunks
>> sind grusel ;-)
>
> Hey, ANU! Amigas Not Unix! Hier hat nicht jeder seinen
>eigenen, privaten Adressraum. Mit der Zahl der Hunks steigen die
>Chancen, dass sich ein Programm noch in den fragmentierten
>Speicher zwaengen kann. Oder sei's auch nur, dass angeknabberter
>Speicher besser ausgenutzt wird.

Naja... ANU, but you can get quite close;-)) Ausserdem, gcc ist sowieso nix
fuer knapp bestueckte Amigas, von daher brauche ich mir auch kein schlechtes
Gewissen zu machen ;-)

>> A4-laden geht mit gcc und ixemul.library uebrigens auch
>> in residenten Programmen, re-aetsch ;-)
>
> Auch bei Interrupt-Funktionen? Nicht, dass es nicht ginge,
>aber... Ich vermeide es sowieso, globale Daten aus Interrupts zu
>veraendern, und ziehe is_Data vor.

Wenn Du weisst wie;-) Direkt gehts nicht, aber wenn Du is_Data geschickt
setzt (nicht umbedingt auf A4, es geht auch anders) ... Na, ist zur Zeit
noch leicht restricted auf Leute (wie ich;-)) die die Source kennen;-))

Matthias Zepf

unread,
Jul 13, 1992, 5:36:45 AM7/13/92
to
In article <TGPkr*K...@germal.bs.open.de> g...@germal.bs.open.de
(Gerald Malitz) writes:
> > Ich bin fuer `so wenig Hunks wie moeglich', sonst frustets mich
> > wieder wenn die HD-LED beginnt zu blinken, anstelle schoen brav
> > zu leuchten, wenn ich ein Proggy lade... Daher, mehrere Datenhunks
> > sind grusel ;-)
> Hey, ANU! Amigas Not Unix! Hier hat nicht jeder seinen
> eigenen, privaten Adressraum. Mit der Zahl der Hunks steigen die
> Chancen, dass sich ein Programm noch in den fragmentierten
> Speicher zwaengen kann. Oder sei's auch nur, dass angeknabberter
> Speicher besser ausgenutzt wird.

Naja, ein gutes Mittelmass ist sicher die beste Loesung.

> Ist das mit der Ladezeit den so gravierend?

Allerdings ... Ein Beispiel ist "Online!" von MSS. Das besteht aus
gut 200 Hunks (zumindest das letzte Update welches ich bekommen habe)
und braucht auch auf einem A3000 mit schneller Platte entsprechend
lang zum Laden.

Gruss, Matthias
--
-- Matthias Zepf, Riegelaeckerstrasse 27, 7250 Leonberg, Germany --
-- +49 7152 41917 Email: ag...@amylnd.stgt.sub.org (NeXTmail) --

Andreas M. Kirchwitz

unread,
Jul 14, 1992, 9:00:17 AM7/14/92
to

>Allerdings ... Ein Beispiel ist "Online!" von MSS. Das besteht aus
>gut 200 Hunks (zumindest das letzte Update welches ich bekommen habe)
>und braucht auch auf einem A3000 mit schneller Platte entsprechend
>lang zum Laden.

"OnLine!" bedient die serielle Schnittstelle ja auch mit Busy Waiting.
Was hast Du da erwartet? ;-)
--

0 new messages