Forum: PC-Programmierung Zeiger auf konstante Arrays in Typdeklaration


von cfan (Gast)


Lesenswert?

1
C-Code

Hallo C-Kollegen,

für ein ModBus-Routing benötige ich folgendes Konstrukt:

typedef struct
{
  Typ1_t const * pTyp1;
  Typ2_t const * pTyp2;
}
Typ12_t;

Beide Elemente sollen auf konstante Arrays ihres Typs zeigen.
Diese Arrays müssen gleich lang sein, da dies eine Mapping werden soll.

Ich will nun schon in der Typdeklaration diese Beschränkung erreichen, 
damit beim Instanziieren mit Konstanten schon der Compiler einen Fehler 
meldet, wenn die benutzten konstanten Arrays nicht die gleiche Länge 
haben.

Ich habe NICHT die Möglichkeit, ein konstantes Array mit dem erzeugten 
Typ "Typ12_t" anzulegen, denn das konstante Array "pTyp1" soll auf 
verschiedene "pTyp2" gemappt werden können, aber trotzdem nur 1x im 
Speicher liegen.
Hat da jemand eine Idee?

Übrigens: Die Arrays sollen zwar konstant und gleich lang sein, diese 
Länge soll in der Typdefinition aber variabel sein, heisst : Bei der 
Instanziierung mitgegeben werden , wie z.B. bei : const int feld[] = 
{1,2,3};

Danke und viele Grüße,
cFan

von B. S. (bestucki)


Lesenswert?

cfan schrieb:
> Hat da jemand eine Idee?

In C ist dein Vorhaben so nicht möglich, aber du könntest die Grösse des 
Arrays in der Struktur mitgeben und zur Laufzeit prüfen. Diese Prüfung 
könntest du, falls gewünscht, mit #ifndef NDEBUG aus dem finalen Code 
rausschmeissen.

Evt. liesse sich das mit schwarzer Präprozessormagie bewerkstelligen, 
gut lesbar ist das aber wahrscheinlich nicht.

Mit C++ und Templates könnte man das Problem ohne Mühe erschlagen, weiss 
aber nicht, ob du C++ verwenden willst/kannst/darfst.

von Rolf M. (rmagnus)


Lesenswert?

Man könnte einen Zeiger auf ein Array nutzen. Dann ist die Größe Teil 
des Typs und der Zeiger ist nicht kompatibel zu einem auf ein Array der 
falschen Größe. Man braucht dann allerdings beim Zugriff immer die 
zusätzliche Dereferenzierung.
1
typedef int Typ1_t;
2
typedef float Typ2_t;
3
4
5
typedef struct
6
{
7
  Typ1_t const (*pTyp1)[10];
8
  Typ2_t const (*pTyp2)[20];
9
}
10
Typ12_t;
11
12
const Typ1_t x[5];
13
const Typ2_t y[3];
14
15
const Typ1_t a[10];
16
const Typ2_t b[20];
17
18
Typ12_t z = { &x, &y}; // Fehler
19
Typ12_t c = { &a, &b}; // In Ordnung

In C++ könnte man das gleiche mit einer Referenz auf ein Array machen 
und sich so die zusätzliche Derferenzierung einsparen. Da braucht man 
gar kein Template dafür.


PS: Hmm, vielleicht hab ich's auch falsch verstanden. Dachte, du willst 
die Array-Länge in Typ12_t vorgeben, aber anscheinend sollen nur die 
beiden Arrays gleich lang sein, aber nicht mit einer vorgegebenen Länge. 
Dann hilft das natürlich nicht.

: Bearbeitet durch User
von Mikro 7. (mikro77)


Lesenswert?

cfan schrieb:

> Beide Elemente sollen auf konstante Arrays ihres Typs zeigen.
> Diese Arrays müssen gleich lang sein, da dies eine Mapping werden soll.

Was spricht dagegen die Anzahl der Elemente der Arrays per pre-processor 
einfach zu vergleichen? Hier eine paar nette Ideen für static asserts in 
C: http://stackoverflow.com/questions/3385515/static-assert-in-c

So ein static assert kannst du dann bspw. unmittelbar vor deiner Typ12_t 
Instanz platzieren. Oder du bastelst dir ein Makro für die 
Instantiierung, das auch die Größen vergleicht.

> Übrigens: Die Arrays sollen zwar konstant und gleich lang sein, diese
> Länge soll in der Typdefinition aber variabel sein, heisst : Bei der
> Instanziierung mitgegeben werden , wie z.B. bei : const int feld[] =
> {1,2,3};

Die Anzahl der Elemente ist auch hier einfach zu bestimmen: 
sizeof(feld)/sizeof(feld[0])

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.