Zeiger auf konstante Arrays in Typdeklaration

Gast #4647896
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
#4648391
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.
#4648483
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.
#4648782
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])

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