Forum: Compiler & IDEs sizeof nicht konstant?


von Walter T. (nicolas)


Lesenswert?

Hallo zusammen,
ich habe mal wieder gemerkt, daß ich Verständnislücken im Bereich 
"Konstanten" unter C habe:

Ich habe ein großes Struct definiert:
1
const conf_t Conf[] =
2
{
3
  {   // Stop
4
    .GPIOx    = GPIOA,
5
    .GPIO_Pin = GPIO_Pin_0,
6
    //[...]
7
  },
8
9
  {   // Pause, feed hold
10
    .GPIOx    = GPIOA,
11
    .GPIO_Pin = GPIO_Pin_1,
12
    //[...]  
13
  }
14
  //[...]
15
},
16
17
const uint32_t nConf = sizeof(Conf)/sizeof(Conf[0]);
Die Größe der Konstanten "nConf" ist zur Compilezeit bekannt. Erzeuge 
ich innerhalb einer Funktion allerdings ein Array mit dieser Größe:
1
void fcn(void)
2
{
3
   static uint_fast8_t helpbuf[nConf];
4
5
6
}
so wird mir das mit der Fehlermeldung
1
   error: storage size of 'helpbuf' isn't constant
quittiert. Beides ist übrigens in der gleichen .c-Datei.

Was veranlaßt den Compiler zu der Behauptung, daß "nConf" kein zur 
Compilezeit bekannter, konstanter Ausdruck sei?

Die "Lösung" für die Implementierung kenne ich natürlich: Mit
1
#define NCONF (sizeof(Conf)/sizeof(Conf[0]))
2
void fcn(void)
3
{
4
   static uint_fast8_t helpbuf[NCONF];
5
}
bekommt der Compiler seinen konstanten Ausdruck und ist zufrieden. Mich 
interessiert also nur: Warum ist eine Konstante kein konstanter 
Ausdruck?

Viele Grüße
W.T.

von Klaus W. (mfgkw)


Lesenswert?

Erstmal ist const nicht die Aussage, daß ein Wert wirklich konstant sein 
muß, sondern nur dein Versprechen, den Wert im Geltungsbereich nicht zu 
ändern.

Für klassische C-Compiler ist das Grund genug, den Wert auch nicht als 
Konstante zu betrachten und verbietet deshalb die Verwendung für eine 
Feldgröße.

Also mit C89/ISO-C90 geht es nicht.
Ab C99 und mit C++ dann wieder doch...

von Markus F. (mfro)


Lesenswert?

Das Schlüsselwort "const" definiert keine Konstante - zumindest nicht in 
C.

Eine const deklarierte Variable bleibt eine Variable. const bedeutet 
lediglich, daß Du beabsichtigst, die Variable innerhalb des so 
deklarierten Gültigkeitsbereiches nicht zu verändern. Sonst nichts.

Daß das Schlüsselwort ungünstig gewählt war, haben die C-Erfinder längst 
begriffen, lässt sich aber nicht mehr ändern. Wenn man noch mal neu 
anfangen würde, würde das wahrscheinlich "readonly" heißen.

von const2const (Gast)


Lesenswert?

Walter Tarpan schrieb:
> Conf[]

Walter Tarpan schrieb:
> nConf = sizeof(Conf) ...

nConf ergibt sich aus einem offenem array. Schreib eine Zahl in die 
eckige Klammer und - wenn es sich nicht ändern soll - noch ein const 
davor.

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Klaus Wachtler schrieb:
> Also mit C89/ISO-C90 geht es nicht.
> Ab C99 und mit C++ dann wieder doch...

Nö, mit C99 (oder C11) geht das auch nicht weil helpbuf[] static ist.

von Dosmo (Gast)


Lesenswert?

Walter Tarpan schrieb:
1
void fcn(void)
2
{
3
  static uint_fast8_t helpbuf[nConf];
4
}

Das Problem ist, daß das Array statisch ist, d.h. es liegt an einer 
festen Adresse und hat eine feste Größe, die sich zur Laufzeut nicht 
ändern kann/darf.
Hierzu braucht es eine Größenangabe, die über die gesamte 
Programmlaufzeit unverändert bleibt.
Der C-Compiler akzeptiert hier keine Variable, auch dann nicht wenn sie 
mit dem Qualifier "const" versehen ist. Wie oben schon erklärt wurde, 
beschreibt "const" eher eine Absichtserklärung, die Variable nicht zu 
beschreiben.

von Klaus W. (mfgkw)


Lesenswert?

Johann L. schrieb:
> Nö, mit C99 (oder C11) geht das auch nicht weil helpbuf[] static ist.

auch wieder wahr...

Wobei sich die Frage stellt, warum es static ist.
Daß es Sinn macht, sehe ich aus dem Zusammenhang hier nicht, aber 
vielleicht hat er ja Gründe dafür.

: Bearbeitet durch User
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.