Hallo,
ich programmiere in C im Atmelstudio 6.2 für den ATMEGA2560.
In einem Header habe ich folgende Strukturen
1
#define ungueltig 4294967295
2
#define namelenght 15
3
4
uint32_tSerienNummer;
5
uint8_tTestschrittAnzahl;// ? Wird im eigentlichen Testprogramm neu deklariert und initialisiert.
6
7
typedefenum{
8
Spannung,
9
// AC,
10
// aBit,
11
// aByte,
12
setBit,
13
resetBit,
14
// TBReceive,
15
TBSend,
16
// TBSendReceive,
17
TBSeriennummer,
18
TBSNNetzteil,
19
TBTuerOeffner,
20
startTime_s,
21
stopTime_s,
22
WaitForDigInHigh,//wartet bis DigIn(uint8_t mask) == High, setzt Programm dann fort
23
Delay_ms,
24
}t_eMessArt;
25
26
typedefstruct{
27
t_eMessArtmessart;
28
uint8_tretry;
29
void*argument;
30
}t_sAction;
31
32
typedefstruct{
33
charname[namelenght];
34
charmin_sign;
35
charmax_sign;
36
charist_sign;
37
uint64_tmin;
38
uint64_tmax;
39
uint64_tist;
40
uint8_tactioncount;
41
boolausgefallen;
42
t_sActionactions[];
43
}t_sTestschritt;
Diese werden in einem anderen Header korrekt initialisiert:
1
t_sMessArgumentVDC_KL1_KL2Argument={
2
.High=E1_H,
3
.Low=E1_L,
4
.Range=&Range_200V,
5
.AC=false,
6
};
7
8
t_sTestschrittVDC_KL1_KL2={
9
.name="VDC Kl1 Kl2\n",
10
.min_sign='-',
11
.max_sign='-',
12
.ist_sign='-',
13
.min=350000000,
14
.max=300000000,
15
.ist=ungueltig,
16
.actioncount=1,
17
.ausgefallen=true,
18
.actions={
19
{.messart=Spannung,
20
.retry=3,
21
.argument=&VDC_KL1_KL2Argument,
22
}
23
}
24
};
Jetzt brauche ich aber einen Testschritt t_sTestschritt mit 20 actions.
Ich versuche das so zu deklarieren:
1
t_sActionFileAction[20];
2
3
t_sTestschrittFileTestschritt={
4
.actioncount=20,
5
.ausgefallen=true,
6
.actions=FileAction
7
};
Das haut mir aber der Compiler um die Ohren.
1
Warning 1 missing braces around initializer [-Wmissing-braces] C:\Dokumente und Einstellungen\ralf.COMANCHE\Eigene Dateien\Elektronik\AVR\7573\testprogramm\testschritte.h 67 1 7573
2
Warning 2 (near initialization for 'FileTestschritt.actions') [-Wmissing-braces] C:\Dokumente und Einstellungen\ralf.COMANCHE\Eigene Dateien\Elektronik\AVR\7573\testprogramm\testschritte.h 67 1 7573
3
Error 3 incompatible types when initializing type 'enum <anonymous>' using type 'struct t_sAction *' C:\Dokumente und Einstellungen\ralf.COMANCHE\Eigene Dateien\Elektronik\AVR\7573\testprogramm\testschritte.h 67 1 7573
Wie kann ich zur CompileZeit dem Testschritt ein Array von 20 t_sAction
zuweisen?
Ralf W. schrieb:> Wie kann ich zur CompileZeit dem Testschritt ein Array von 20 t_sAction> zuweisen?
Gar nicht.
So ein flexible array member besitzt im Rahmen der Struktur selbst
erst einmal keinen Speicher. Daher kann man auf diese nur dann
zugreifen, wenn sichergestellt ist, dass irgendwo anders her Speicher
dafür bereitgestellt worden ist. Das bedeutet letztendlich, dass
der ganze Konstrukt nur dann Sinn hat, wenn man auf die Struktur über
Zeiger zugreift.
Sinngemäß findet sich das im Standard in Abschnitt “6.7.2 Type
specifiers”, Absatz 18 wieder:
1
As a special case, the last element of a structure with more than one
2
named member may have an incomplete array type; this is called a flexible
3
array member. In most situations, the flexible array member is ignored.
4
In particular, the size of the structure is as if the flexible array
5
member were omitted except that it may have more trailing padding than
6
the omission would imply. Howev er, when a . (or ->) operator has a left
7
operand that is (a pointer to) a structure with a flexible array member
8
and the right operand names that member, it behaves as if that member
9
were replaced with the longest array (with the same element type) that
10
would not make the structure larger than the object being accessed; the
11
offset of the array shall remain that of the flexible array member, even
12
if this would differ from that of the replacement array. If this array
13
would have no elements, it behaves as if it had one element but the
14
behavior is undefined if any attempt is made to access that element or
Hallo,
irgendwie geht es halt doch, wenn ich es so schreibe:
1
t_sTestschrittFileTestschritt={
2
.actioncount=20,
3
.ausgefallen=true,
4
.actions={
5
{},
6
{},
7
}
8
};
Nach meinem dafürhalten habe ich jetzt ein Array für .actions
mit 2 Elementen. Schreibe ich da jetzt 20 leere Klammern habe ich
meine 20 Elemente.
Aber dafür muß es doch eine bessere Schreibweise geben. Oder?
Ralf W. schrieb:> Aber dafür muß es doch eine bessere Schreibweise geben. Oder?
Sei doch froh, dass es dafür überhaupt eine gibt.
Dürfte eine GCC-Erweiterung sein, der sich damit also schon mal
über das vom Standard vorgeschriebene Maß hinaus bewegt hat.
problem ist halt das der vergebene speicher feststehen muss.
deine {} klammern tun das gleiche wie actions[20]
sie reservieren den speicher.
wenn du das dynamisch brauchst dann wirst du um malloc/free nicht
drumherum kommen.
Ralf W. schrieb:> Korrekt muß die struct t_sTestschritt so deklariert werden.
Du kannst auch das mit dem flexible array member benutzen. Die
Idee ist dabei dann nur, dass du den eigentlichen Speicher dafür
irgendwo in passender Größe per malloc() beschaffst. sizeof(struct)
kannst du benutzen, um alles außer dem flexible array zu
bestimmen, d. h. wenn du 20 Elemente im Array hinter der eigentlichen
struct haben willst, allozierst du
1
malloc(sizeof(structxxx)+20*sizeof(arrayyy))
Davon darfst du dann einen Typecast auf einen Zeiger auf die struct
machen und nun auf den zusätzlichen Speicher am Ende typsicher
zugreifen.