Rolf B: c Mathematik über Binary

Beitrag lesen

Hallo pl,

wollte das zu Hause im VS2017 ausprobieren und musste feststellen, dass ich den C++ Compiler nicht installiert hatte. Sehr merkwürdig, ich hatte doch vor 2 Jahren oder so mit der Anwendung der Intel SIMD-Instruktionen für's Schnellbacken von Mandelbrötchen gespielt und ihn da noch verwendet.

Jedenfalls habe ich dann bei der Gelegenheit einen Online-Spielplatz für GCC entdeckt: https://www.tutorialspoint.com/compile_c_online.php

und damit ausprobiert, ob das, was ich hier empfehle, Illusion oder Wirklichkeit ist.

char *a = "ABCD";
printf("%d\n", *(uint8_t*)a + 1); // 66

Das ist potenziell pöse und kann Dich zu Poden chleudern. Daher eine Testfrage: sage mir, was dieses Statement ausgibt, wenn a nicht mit "ABCD", sondern mit "ALARM" initialisiert wird.

Ein Hinweis noch für solchen Code: Du weist a einen Zeiger auf das String-Literal "ABCD" zu. Dieses Literal liegt möglicherweise, aber nicht zwingend, in einem constant data Bereich deines Executables schreibgeschützt herum. D.h. wenn Du damit a[1]='X'; programmierst, gibt's einen Absturz wegen Schreibens auf schreibgeschützten Speicher. Die von mir oben verlinkte Sandbox gibt dann aus:

the monitored command dumped core
sh: line 1: 134208 Segmentation fault      timeout 10s main

Schlimmer wäre es, wenn dieser Absturz nicht käme. Denn dann würdest Du den Initializer "ABCD" verändern und wenn Du später nochmal an diese Stelle kommst, würdest Du falsch initialisieren.

Es ist darum besser, sich hier vom Compiler helfen zu lassen; und ein sensibler Compiler sollte solchen Code ohnehin schon direkt anmeckern. Es fehlt nämlich ein const. Mit

const char* a = "ABCDE";

haut Dir der Compiler auf die Finger, wenn Du an a[1] was zuweisen willst. Mit const sollte man großzügig sein, jeder Pointer, über den man nur lesen will, sollte es bekommen. Gerade in Parameterleisten von Funktionen, die einen Pointer bekommen und mit diesem Pointer nur lesen, ist das von Bedeutung, dann sieht der Aufrufer gleich, dass ihm über diesen Pointer keine Daten kaputt gemacht werden.

const ist allerdings nicht gaaanz einfach. Es gibt diese 3 Varianten, und jede heißt was anderes:

      char* const a = "ABCDE";
const char*       b = "ABCDE";
const char* const c = "ABCDE";

a ist ein char*, den Du nicht ändern darfst (der Pointer selbst ist unveränderlich). Das, worauf a zeigt, darfst Du aber ändern. b ist ein char*, bei dem Du die Adresse auf die er zeigt, nicht ändern darfst. Den Pointer selbst aber schon. Und c ist ein unveränderlicher char* auf eine read-only Adresse. Ich habe alle 3 schon gesehen, vor allem in Deklarationen von Library-Code. Eselsbrücke: das const wirkt auf das, was direkt rechts daneben steht.

Happy Buffer Overflowing
Rolf

--
sumpsi - posui - clusi