Forum: Compiler & IDEs type/typedef of struct member element?


von Apollo M. (Firma: @home) (majortom)


Lesenswert?

Compiler GCC V5.x-11.x

Problem#1:
Wie kann ich mit typedef den Typ bestimmen von struct Elementen e.g. 
hier d?
1
//"prototype"
2
typedef struct {volatile size_t r, w; uint8_t d[0];} queue_t;

Problem#2:
Beispielweise braucht queue_get() queue_t, die Struktur ist aber bzgl. 
dem Array variabel, wie definiert man den Prototype von queue_t besser 
als oben, da ist uint8_t d[0] nur eine Not.

Die eigentliche queue struct wird mit dem Makro QEUEU() erzeugt.

Problem#3
In queue_get() will der GCC die void Verwendung *pd= ... nicht 
akzeptieren?! Wie löse ich das Problem.

Problem#4
Verwendung ...
1
QUEUE2(rxBuf, uint16_t, 32);
2
uint16_t = d;
3
queue_get((queue_t*)&rxBuf, &d);
Hier stört mich das (queue_t*), hängt natürlich mit Problem#2 zusammen.

Wenn das alles Murks ist, wie gehts besser/richtig?

Ich habe eine Variante über ein Makro in Verwendung, dass alle queue 
Funktionen direkt für die jeweilige qeueu sauber definiert, ABER wenn 
viele queues verwendet werden, dann könnte die code size stören, da für 
jede Qeue die drei gleichen Funktionen erzeugt werden.
1
#define QUEUE(QNAME, QTYPE, QNUM) struct {volatile size_t r, w; QTYPE d[QNUM];} QNAME
2
3
qErr_t queue_get(queue_t *const pq, void* const pd) {
4
  if (pq->w-pq->r == 0) return QEMPTY;
5
  *pd= pq->d[(pq->r)++];
6
  if (pq->r>= mQSIZE(pq->d)) {pq->r = 0; return QSUCCESS;}
7
}

von Apollo M. (Firma: @home) (majortom)


Lesenswert?

Apollo M. schrieb:
> über ein Makro

... und für die macro Liebhaber oder gibt es auch Hasser dort draußen?!
1
//queue return values
2
typedef enum {QSUCCESS, QEMPTY, QOVERRUN} qErr_t; 
3
4
//queue options
5
#define QCALL_REF *pd  //call be reference
6
#define QCALL_VAL d    //by value
7
#define QOVRP_OFF //queue overrun write protection off
8
#define QOVRP_ON return QOVERRUN //write protection on
9
10
//helper function
11
#define mQSIZE(s) (sizeof(s)/sizeof((s)[0]))
12
    
13
/*****************************************************************************/                                             
14
#define QUEUE(QNAME, QTYPE, QNUM, QCALL_RV, QOVRP) \
15
/*****************************************************************************/ \
16
struct { \
17
  volatile size_t r, w; \
18
  volatile QTYPE d[QNUM]; \
19
} QNAME; \
20
\
21
/*****************************************************************************/ \
22
void QNAME##_init() { \
23
/*****************************************************************************/ \
24
  QNAME.r= QNAME.w= 0; \
25
} \
26
\
27
/*****************************************************************************/ \
28
qErr_t QNAME##_put(const QTYPE QCALL_RV) { \
29
/*****************************************************************************/ \
30
  if ((QNAME.r+1-QNAME.w) % mQSIZE(QNAME.d) == 0) QOVRP; \
31
  QNAME.d[(QNAME.w)++]= QCALL_RV; \
32
  if (QNAME.w >= mQSIZE(QNAME.d)) {QNAME.w= 0; return QSUCCESS;} \
33
} \
34
\
35
/*****************************************************************************/ \
36
qErr_t QNAME##_get(QTYPE *const pd) { \
37
/*****************************************************************************/ \
38
  if (QNAME.w-QNAME.r == 0) return QEMPTY; \
39
  *pd= QNAME.d[(QNAME.r)++]; \
40
  if (QNAME.r >= mQSIZE(QNAME.d)) {QNAME.r= 0; return QSUCCESS;} \
41
}

von Apollo M. (Firma: @home) (majortom)


Lesenswert?

Apollo M. schrieb:
> Wie kann ich mit typedef

... typeof!

von Oliver S. (oliverso)


Lesenswert?

Apollo M. schrieb:
> wie definiert man den Prototype von queue_t besser
> als oben, da ist uint8_t d[0] nur eine Not.

Einfach die 0 weglassen...

Oliver

von Apollo M. (Firma: @home) (majortom)


Lesenswert?

Oliver S. schrieb:
> Einfach die 0 weglassen...

... dann gibt es eine Brandmauer mit sizeof()

von flexible (Gast)


Lesenswert?

Apollo M. schrieb:
> die Struktur ist aber bzgl.
> dem Array variabel, wie definiert man den Prototype von queue_t besser
> als oben, da ist uint8_t d[0] nur eine Not.

Ein variables Array in einer Struktur ist möglich (muss am Strukturende 
stehen). Ab C99 oder ab C11?

Die Dimension des Array wird weggelassen (nicht mal 0 ist erlaubt) und 
man reserviert später dafür benötigten Platz (malloc).

https://www.geeksforgeeks.org/flexible-array-members-structure-c/

von mh (Gast)


Lesenswert?

flexible schrieb:
> Apollo M. schrieb:
>> die Struktur ist aber bzgl.
>> dem Array variabel, wie definiert man den Prototype von queue_t besser
>> als oben, da ist uint8_t d[0] nur eine Not.
>
> Ein variables Array in einer Struktur ist möglich (muss am Strukturende
> stehen). Ab C99 oder ab C11?
>
> Die Dimension des Array wird weggelassen (nicht mal 0 ist erlaubt) und
> man reserviert später dafür benötigten Platz (malloc).

Du hast die letzten beiden Beiträge vor deinem Beitrag gelesen?

von Apollo M. (Firma: @home) (majortom)


Lesenswert?

flexible schrieb:
> Die Dimension des Array wird weggelassen (nicht mal 0 ist erlaubt) und
> man reserviert später dafür benötigten Platz (malloc).

... bekannt
Die benutzte struct verwendet aber kein variables Array, die später 
erzeugte und ref. Queue struct hat eine feste array size.

Mein Ansatz sieht irgendwie gebastelt aus, das muss anders gehen ...

von Apollo M. (Firma: @home) (majortom)


Lesenswert?

Apollo M. schrieb:
> die Struktur ist aber bzgl.
> dem Array variabel,

... variabel meint hier - wird zur Compiler Laufzeit erst definiert.

von Oliver S. (oliverso)


Lesenswert?

Es wird langsam Zeit für einen Umstieg auf C++.

Oliver

von Apollo M. (Firma: @home) (majortom)


Lesenswert?

Oliver S. schrieb:
> Umstieg auf C++.

... Nee, ich bin gerade eher bei Rust und Python gelandet, aber für 
meine kleinen Bastelprojekte auf PIC12-18xx ist C meine Wahl.

Ich habe auch eine C++ Version, da ist das einfach und ein Selbstläufer.

von Apollo M. (Firma: @home) (majortom)


Lesenswert?

... die Fragen sind gelöst - wie vermutet, es gibt keine Lösung dazu mit 
C.
Also bleibe ich bei meinen macro functions

von STK500-Besitzer (Gast)


Lesenswert?

Apollo M. schrieb:
> ... variabel meint hier - wird zur Compiler Laufzeit erst definiert.

Dann verwendet man ein Makro, das die Array-Größe programmweit 
definiert.

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.