Pointer-Konstrukt mit Array -> böse?

Gast #2887238
Lesenswert?

Hallo,

ich hätte eine Frage:
Wird folgendes Konstrukt funktionieren?
Ist es programmierstil-mässig böse?
1
unsigned int my_val;
2
unsigned char my_val_a[2];
3

4
&my_val_a = &my_val;
5

6
my_val = 0xFF00;
7

8
//Zugriff auf LSB (0x00)
9
char foo = my_val_a[0];
10

11
//MSB (0xFF)
12
foo = my_val_a[1];

Richtig?!

Grüsse
#2887248
Lesenswert?

elektrodejns schrieb:

> unsigned int my_val;
> unsigned char my_val_a[2];
>
> &my_val_a = &my_val;


Jags mal durch den Compiler und sieh nach was er dazu zu sagen hat :-)



Merk dir eine Grundregel in C: Arrays sind Bastarde. Es gibt praktisch 
nichts, was du mit einem Array als ganzes machen kannst. Auch 
Zuweisungen nicht.


Und 2-tens (das dürfte die Idee in deinem Code gewesen sein): Wenn eine 
Variable eine Adresse hat, dann hat sie die. Die kriegt sie vom 
Compiler/Linker zugewiesen und es gibt nichts was du daran ändern 
könntest. Es mag zwar relativ naheliegend sein, eine Variable mittels

   int i;
   &i = 4711;

an die Speicheradresse 4711 zu knüppeln, nur spielts das eben nicht.
#2887269
Lesenswert?

Karl Heinz Buchegger schrieb:

> Und 2-tens (das dürfte die Idee in deinem Code gewesen sein): Wenn eine
> Variable eine Adresse hat, dann hat sie die. Die kriegt sie vom
> Compiler/Linker zugewiesen und es gibt nichts was du daran ändern
> könntest.

Um genau zu sein, gibt es natürlich bei diversen Compilern 
Erweiterungen, mit denen man eine Variable bei der Definition an eine 
Speicheradresse nageln kann. Aber das geschieht bei der Definition. Im 
Nachhinein geht da nichts mehr.
#2887273
Lesenswert?

> unsigned int my_val;
> unsigned char my_val_a[2];
>
> &my_val_a = &my_val;

Offenbar versuchst du da gerade die "union" neu zu erfinden.

Das über eine Union zu machen ist zwar streng genommen nicht koscher, 
aber so dermaßen weit verbreitet, dass du das bedenkenlos machen kannst. 
Noch besser wäre es natürlich, es standardkonform und portabel per 
Shift&Mask zu machen.
#2887563
Lesenswert?

Simon K. schrieb:
> Stefan Ernst schrieb:
>> aber so dermaßen weit verbreitet, dass du das bedenkenlos machen kannst.
>
> What?!?! Nur weil es so viele (falsch) machen ist garantiert, dass es
> funktioniert? Also soweit ich im Programmierbusiness bin, funktioniert
> Programmierung so nicht.
> Garantiert ist nur das, was der C-Standard da sagt. Und der garantiert
> sowas eben nicht.

Ich bin durchaus bei dir, was Beachtung dessen betrifft, was vom 
Standard zugesagt wird und was nicht.
Allerdings stimmt es schon, was Stefan sagt: Diese Union-Überlagerung 
gibt es, seit es C gibt. Es ist kein einziger Compiler bekannt, bei dem 
die Dinge nicht so funktionieren würden (und es gibt auch keinen 
wirklichen technischen Grund dafür). De facto hat sich hier die 
'normative Kraft des Faktischen' eingebürgert, so dass eher zu erwarten 
ist, dass ein Compilerhersteller dieses Feature 'nachrüstet', anstatt 
alle vor den Kopf zu stossen, falls es mal notwendig sein sollte.

Warum es dann nicht im Standard steht? Weil es formal gesehen eigentlich 
falsch ist und man damit etwas fordert, was man tunlichst aus dem 
Standard raushalten will. Im Standard wurde viel wert darauf gelegt, 
dass Maschinenabhängigkeiten möglichst draussen bleiben (der Standard 
lässt zb die Frage nach der Darstellung von negativen Zahlen völlig 
aussen vor. Trotzdem programmieren wir immer so, als ob 2-er Komplement 
garantiert wäre). Im Standard gibt es keine Zusicherung, dass ein C-Byte 
dasselbe wie ein Byte auf physikalischer Ebene ist. Und ohne diese 
Zusicherung ist es schwierig zu definieren, wie so eine Überlagerung 
funktionieren soll.
Persönliche Seite #2888115
Lesenswert?

Prinzipiell kann man sowas ja schon machen, nicht ohne Grund nennen 
manche C einen "besseren Makro Assembler"

Vielleicht ist es auch ein klein wenig schneller als shift & mask. (Würd 
ich nicht wetten, Compiler sind manchmal recht clever.)

Wenn es denn sein muss würde ich es über eine Union machen. Dann ist 
einigermaßen offensichtlich, dass es hier 2 unterschiedliche 
Zugriffswege auf die selben Daten gibt. + Kommentar warum und weshalb.

ABER:
Portabel ist der Code damit nicht mehr zwingend. Wenn sich die 
Byte-Order der Platform ändert kann es Probleme geben.

Ich bin da mal böse auf die Nase gefallen. Simuliert auf der 
Entwicklungsumgebung hat alles funktioniert, auf der Zielplatform ging 
gar nichts. Und es gab keinen Debugger, kein Log, nichts.
Ich hab' dann ne Debug-LED angelötet und erst nach Stunden rausgefunden, 
dass der Simulator die Byte-order der Zielplatform nicht richtig 
simuliert hat.

Grüße, Joey

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren