Forum: Compiler & IDEs invalid application of 'sizeof' to incomplete type 'char[]'


von brechbunkt (Gast)


Lesenswert?

Hallo,

ich habe diese drei Dateien hier:

file character.c:
1
char xxxx[] = "abcdef";
file character.h:
1
extern char xxxx[];

file main.c:
1
void main (void)
2
{
3
   ...
4
   print_ulong( sizeof(xxxx) );
5
   ...
6
}

Möchte ich diese nun compilieren, erhalte ich die Fehlermeldung "invalid 
application of 'sizeof' to incomplete type 'char[]'".
Definiere ich das Array "xxxx" direkt in der Datei main.c, geht alles in 
Ordnung. Aber gibt es nicht auch eine Möglichkeit sizeof() zu nutzen, 
wenn das Array in einer anderen Datei definiert wurde?

: Verschoben durch User
von Joachim D. (Firma: JDCC) (scheppertreiber)


Lesenswert?

Woher soll das der Compiler denn wissen ?

von Karl H. (kbuchegg)


Lesenswert?

brechbunkt schrieb:

> Ordnung. Aber gibt es nicht auch eine Möglichkeit sizeof() zu nutzen,
> wenn das Array in einer anderen Datei definiert wurde?


Frage.

Dieser Code
Datei: a.c
1
extern char c[];
2
3
int main()
4
{
5
}

wieviele Bytes sind im Speicher für c reserviert worden?

Wie, du kannst die Frage nicht beantworten?
Wieso erwartest du dann, dass der Compiler das könnte? So ein Compiler 
ist ja auch kein Wunderwuzzi. Wenn er a.c compiliert, dann interessiert 
ihn nur der Inhalt von a.c. Was in b.c steht, interessiert nicht.

Das ist das vielleicht wichtigste Prinzip, das am öftesten für 
Verwirrung sorgt:
C kennt in der Sprache keinen Projektgedanken, so wie das in anderen 
Sprachen ist. Ein C-Compiler compiliert jede Übersetzungseinheit (salopp 
gesagt: jedes C-File) für sich alleine und ohne Ansehen von anderen 
C-Dateien.

: Bearbeitet durch User
von brechbunkt (Gast)


Lesenswert?

Hmmmm..... da er spätestens beim linken dann alle Infos beisammen hat, 
wäre ich davon ausgegangen, dass er dann wüsste wie viel Bytes verwendet 
werden und dann somit alles wieder klar ist.

von Karl H. (kbuchegg)


Lesenswert?

brechbunkt schrieb:
> Hmmmm..... da er spätestens beim linken dann alle Infos beisammen hat,


Ein Linker ist kein Compiler, auch wenn ich zugeben muss, dass moderne 
Linker in der Optimierung schon einiges können.

Aber das war ganz sicher nicht 1970 so, als die grundlegenden Prinzipien 
von C festgelegt wurden. Damals galt: Ein Compiler übersetzt Einheiten 
in Object-Code, ein Linker baut die Object-Code Einheiten zum fertigen 
Programm zusammen. Ein Linker beschäftigt sich nur noch damit, 
Adressverweise entsprechend aufzulösen. Alles andere ist Sache des 
Compilers, der unter anderem auch dem Link die Information geben muss, 
an welcher Stelle im Code welche Adresse einzusetzen ist. Aber abgesehen 
davon, hat der Compiler den Object Code schon fix&fertig vorgekaut. Ein 
Compiler kennt die Programmiersprache, ein Linker hat davon keine 
Ahnung. Der löst nur Querverweise auf.
Und an diesem Grundgedanken hat sich seither nichts geändert.

: Bearbeitet durch User
von brechbunkt (Gast)


Lesenswert?

Ok. Ich danke euch für die Antworten. Denke es ist nun alles geklärt.

von Dirk B. (dirkb2)


Lesenswert?

In diesem Fall hängt die Größe des Speicherbereichs von der Länge des 
Textes ab. Die Textlänge kannst du mit strlen ermitteln.

Wenn du die Größe direkt beim Array angibst, dann kannst du diesen Wert 
auch auf andere Art und Weise weitergeben (#define oder const)

von Marc P. (marcvonwindscooting)


Lesenswert?

Karl Heinz schrieb:
> Datei: a.c
> extern char c[];
>
> int main()
> {
> }
>
> wieviele Bytes sind im Speicher für c reserviert worden?

Gegenfrage: warum weiss er es dann hier (C99):
1
void provokation(unsigned n) {
2
  char c [n+1];
3
4
  for (int i=0; i<sizeof c; i++) {
5
    ...
6
  }
7
}

Hehe ;-)

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Marc P. schrieb:
> Gegenfrage: warum weiss er es dann hier (C99):

Weil es ein VLA ist, und das nur funktioniert, wenn er die Länge
bereits weiß.

von Dirk B. (dirkb2)


Lesenswert?

... und weil das Array in der selben Übersetzungseinheit definiert ist.

Das Problem vom TO kam dadurch, dass die Variable als extern deklariert 
ist.

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.