[Allegro] Etwas für C-Programmierer: strcpy() vs. memmove()

Bernhard Eversberg ev at biblio.tu-bs.de
Mo Dez 2 11:48:25 CET 2013


In einem nichtöffentlichen Disput vorige Woche mit Berger schälte sich
heraus, daß es wohl Compiler gibt (speziell unter Ubuntu), die ein
Problem machen mit der Funktion strcpy():
Das Ergebnis eines Aufrufs  strcpy(a,b)  ist laut der Literatur über C
"undefined" (ohne Fehlermeldung), wenn die Strings a und b sich
überlappen. Man mag sich an den Kopf fassen, aber so steht's da.

Kurz und gut, um nicht den gesamten Austausch hier zu reproduzieren,
waren wir hier immer von der Mutmaßung ausgegangen, gestützt jedoch
auf das bekannte Buch von Kernighan und Ritchie, daß die Sache
unproblematisch sei, wenn  b = a+n  ist mit nichtnegativem n.
Anders gesprochen, wenn ein Teilbereich innerhalb von a
nach vorn gezogen werden soll. Nie zeigte sich ein Problem damit.
In anderen möglicherweise kritischen Fällen hatten wir das etwas
umständlichere  memmove()  benutzt, wie es die Literatur rät.
(Z.B. im Falle a>b mit a-b<strlen(b) wäre, wiederum nach K&R beurteilt,
mit einem Debakel zu rechnen!)

Nun also scheinen Bergers Beobachtungen unsere also wohl doch naive
Annahme zu widerlegen.

Was also tun, war die Frage, denn es gibt viele hundert Vorkommnisse
von strcpy in unseren Quellen! Alle überprüfen?

Auf die einfachste, nächstliegende Lösung kamen wir zuletzt:
Wir definieren eine Funktion  stcopy(a,b), die nichts
anderes tut, als  memmove(a,b,strlen(b)+1)  auszulösen, was in
jedem Falle klappt. Nun müssen wir nur noch in allen Quellen
die Ersetzung von  "strcpy("  durch  "stcopy("  vornehmen. Das ist
schlichte Routine-Editierung und geht schnell. Exemplarisch wurde
das mit acon schon gemacht und funktioniert ohne merkliche
Performance-Einbuße, wie sich auch bei einem gezielten Test
bestätigte. Dies mag auch noch vom Compiler abhängen, aber mit
Visual-C++ ist es so.
Die C-Quellen von "atools" (also srch, import, index, qrix) werden
in gleicher Weise entschärft.

Das publizierte Gesamtpaket V33 ist zwar noch ohne diese Änderung
kompiliert, das macht aber nichts, weil der Visual-C++ damit ja
eben keine Zicken macht!

Wir melden Vollzug, sobald die Änderungen erledigt und im SVN sind.
Danach  werden dann *diese* Problemstellen ihre Compilerabhängigkeit
eingebüßt haben. Andere Problemstellen harren noch ihrer Entlarvung als
solcher.

B.E.






Mehr Informationen über die Mailingliste Allegro