Guten Abend, anbei ein Code zur Berechnung des minimalen und maximalen
Wertes eines Arrays. Ich möchte gerne das Array durchlaufen und als
Abbruchbediungung wollte ich den Wert bla: sizeof(zahlen)/sizeof(int)
verwenden. Im main-Programm habe ich es nur zur Überprüfung des Wertes
aufgerufen. bla ergibt aber in der main den Wert 4 und in der Funktion
den Wert 1, wieso ?
#include "pch.h"
#include <iostream>
double MinMaxDurch(int zahlen[]) {
int min = zahlen[0];
int max = zahlen[0];
int summe = 0;
int bla = sizeof(zahlen)/sizeof(int);
for (int i = 0; i < bla; i++) {
if (zahlen[i] < min) min = zahlen[i];
if (zahlen[i] > max) max = zahlen[i];
summe += zahlen[i];
}
printf("Minimum: %d ", min);
printf("Maximum: %d ", max);
return (float)summe/(float)sizeof(zahlen);
return 0;
}
int main()
{
int zahlen[] = {3,7,5,10,122};
int bla = sizeof(zahlen)/sizeof(int);
MinMaxDurch(zahlen);
return 0;
}
weil das Argument 'int zahlen[]' ein einfacher Zeiger ist und damit
keine Grösseninfo übertragen wird. Das musst du mit einem zweiten
Argument 'int AnzzahlElemente' selber hinzufügen.
Oder mit containern der std lib arbeiten.
Marco D. schrieb:> Im main-Programm habe ich es nur zur Überprüfung des Wertes> aufgerufen. bla ergibt aber in der main den Wert 4 und in der Funktion> den Wert 1, wieso ?
int zahlen[] ist in einer Parameterliste äquivalent zu int * zahlen,
also ein Zeiger auf einen int. sizeof zahlen gibt dir daher die Größe
eines Zeigers zurück.
Marco D. schrieb:> double MinMaxDurch(int zahlen[]) {
Schreib das im Kontext von Funktionsparametern lieber als
double MinMaxDurch(int *zahlen) {
Ist sowieso exakt gleich, verarscht dich aber nicht.
Markus E. schrieb:> Aber wieso kommen dann unterschiedliche Ergebnisse raus?> Zahlen[] bzw. Int* müsste doch immer gleich groß sein?
In einer Parameterdeklaration ist das identisch. Aber nur da. An anderer
Stelle sind das zwei Paar Stiefel. Das hier ist keine
Parameterdeklaration:
int zahlen[] = {3,7,5,10,122};
Ich fand es keine gute Idee, dass C die Leute verarscht, indem in
Parameterdeklaration daraus implizit ein Pointer wird.
Entscheidend ist dass in main die Grösse des Arrays bekannt ist. In der
Parameterliste aber nicht, da die Grössenangabe fehlt.
In main kann also sizeof die Grösse des Arrays ermitteln. In der
Funktion aber nur die Grösse des Zeigers. An dieser Stelle ist int *x
und int x [] äquivalent. Wäre hingegen die Grösse ausdrücklich angegeben
worden int x [17] dann würde sizeof diese Information verwenden.
Im C-Standard ist das ausführlich erklärt.
Bemerkung:
Etwas irreführend kann die irrige Annahme sein, dass der Compiler den
gesamten Kontext berücksichtigt. Ein menschlicher Leser, weiss ja, wie
lang das Array ist. Der Compiler betrachtet aber die Funktionen einzeln
ohne ihren Kontext.
Theor schrieb:> Wäre hingegen die Grösse ausdrücklich angegeben> worden int x [17] dann würde sizeof diese Information verwenden.
Bei einem solcherart deklarierten Parameter?
Theor schrieb:> Wäre hingegen die Grösse ausdrücklich angegeben> worden int x [17] dann würde sizeof diese Information verwenden.
Ganz und gar nicht. Ein solcher Art Parameter wäre ebenfalls äquivalent
zu int* x; die 17 an dieser Stelle ist nicht mehr oder weniger wert als
ein Kommentar.
bla (und auch i) sollten vom Typ size_t sein.
Der ist in <stdint.h> definiert.
Beim ersten return aus deiner Funktion berechnest du den Mittelwert
falsch.
Wenn du die Anzahl der Elemente im Array ermittel willst, dann schreib
beim Divisor die ein Element aus dem Array hin
size_t bla = sizeof(zahlen)/sizeof(zahlen]0]);
oder
size_t bla = sizeof(zahlen)/sizeof(*zahlen);
Dann ist da auch noch korrekt, wenn sich der Typ von zahlen ändert.
Bei Übergabe von Arrays an Funktionen solltest du immer die Größe vom
Array mit angeben.
Unbedingt, wenn das Array beschrieben wird.
strcpy ist z.B eine Fehlkonstruktion. strncpy ist auch nicht besser.
tictactoe schrieb:> Theor schrieb:>> Wäre hingegen die Grösse ausdrücklich angegeben>> worden int x [17] dann würde sizeof diese Information verwenden.>> Ganz und gar nicht. Ein solcher Art Parameter wäre ebenfalls äquivalent> zu int* x; die 17 an dieser Stelle ist nicht mehr oder weniger wert als> ein Kommentar.
Du hast recht. Ich habe etwas Falsches geschrieben.
Man siehe 6.5.3.4. der Standards.
C11 http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1570.pdf
C18
http://www.open-std.org/jtc1/sc22/wg14/www/abq/c17_updated_proposed_fdis.pdf
Da muss der Wunsch der Vater des Gedankens gewesen sein.
Und logisch kommt es mir auch vor, denn der Fall int x [17] würde ja
einen kompletten Typen darstellen.
Aber das nur nebenbei.
>> Theor schrieb:
[...]
> Da muss der Wunsch der Vater des Gedankens gewesen sein.> Und logisch kommt es mir auch vor, denn der Fall int x [17] würde ja> einen kompletten Typen darstellen.
Obwohl ...
Das würde zu einer anderen Komplikation führen, wenn nämlich die
Funktion in einem einzigen Programm auf Arrays verschiedener Länge
ausgeführt werden soll. Dann würde für jede Variation der Länge eine
eigene Funktion nötig sein. Ist also schon sinnvoll. Na gut. :-)
Deswegen haben C-Funktionen das typische Idiom, daß sie einerseits einen
Pointer übergeben bekommen und (sofern die Länge nicht fix ist) zweitens
einen Längenparameter vom Typ size_t.
Theor schrieb:> Entscheidend ist dass in main die Grösse des Arrays bekannt ist. In der> Parameterliste aber nicht, da die Grössenangabe fehlt.
Das ist zu kurz gedacht. Es hat nicht direkt mit Größeninformationen zu
tun, sondern damit, dass wir in main ein Array haben, in der
Paramterliste aber einen Zeiger. Das sind zwei ganz unterschiedliche
Dinge.
Dirk B. schrieb:> Bei Übergabe von Arrays an Funktionen solltest du immer die Größe vom> Array mit angeben.> Unbedingt, wenn das Array beschrieben wird.
Ob es beschrieben wird oder nicht, spielt keine Rolle. Wenn man ein
Array übergibt, muss die aufgerufene Funktion auf irgendeine Art wissen,
wie lang das Array ist. Die gängigen Varianten sind ein Array fixer
Länge, ein zusätzlicher Parameter mit der Länge und irgendeine Form von
Ende-Kennung, wie z.B. bei C-Strings das \0 am Ende.
> strcpy ist z.B eine Fehlkonstruktion. strncpy ist auch nicht besser.
Hä?
Rolf M. schrieb:> Dirk B. schrieb:>> Bei Übergabe von Arrays an Funktionen solltest du immer die Größe vom>> Array mit angeben.>> Unbedingt, wenn das Array beschrieben wird.>> Ob es beschrieben wird oder nicht, spielt keine Rolle. Wenn man ein> Array übergibt, muss die aufgerufene Funktion auf irgendeine Art wissen,> wie lang das Array ist. Die gängigen Varianten sind ein Array fixer> Länge, ein zusätzlicher Parameter mit der Länge und irgendeine Form von> Ende-Kennung, wie z.B. bei C-Strings das \0 am Ende.
Ein Array kann auch nur zu einem Teil gefüllt sein.
Beim Lesen spielt es keine Rolle, wie groß das Array ist, wenn man eine
Endekennung hat.
Beim Schreiben möchte man evtl. den ganzen Bereich ausnutzen. Und dann
sollte man die Größe kennen.
1
charfeld[200]="Hallo Welt!";// 12 von 200 belegt
2
strcpy(feld,"hello world!");
>> strcpy ist z.B eine Fehlkonstruktion. strncpy ist auch nicht besser.>> Hä?
Den Fehler kann man zwar durch templates vermeiden wie ich oben gezeigt
habe, allerdings ist das Grundproblem, dass überhaupt mit rohen Arrays
gearbeitet wird in dem Stück C++-Code. Besser von vornherein
std::array<> für statische Arrays einsetzen.
Um das Problem des TO zu verstehen, bitte mal nach "decaying of array
designator" googlen.
Rolf M. schrieb:> Theor schrieb:>> Entscheidend ist dass in main die Grösse des Arrays bekannt ist. In der>> Parameterliste aber nicht, da die Grössenangabe fehlt.>> Das ist zu kurz gedacht. Es hat nicht direkt mit Größeninformationen zu> tun, sondern damit, dass wir in main ein Array haben, in der> Paramterliste aber einen Zeiger. Das sind zwei ganz unterschiedliche> Dinge.>> [...]
Eigentlich finde ich nicht, dass das zu kurz gedacht ist. Eher halte ich
es für plausibel, dass ich einen oder zwei Schritte tiefer gedacht habe.
Zugegeben: Das ich zu kurz gedacht haben soll, provoziert mich auch ein
bisschen. :-) Möglich ist das natürlich schon, aber ich halte Deinen
Einwand nicht für ausschlaggebend für diese Beurteilung.
Aber zum Thema, falls Du darauf eingehen magst:
Ich denke, dass es, - mal vom Standpunkt eines Compilerbauers aus
gesehen -, ausgehend vom Quelltext möglich wäre, die
Grösseninformation eines Array-Parameters der Form "Typ Name [Groesse]"
zu gewinnen.
Ich denke weiter, dass die Umwandlung eines Array-Parameters in einen
Zeiger darauf nicht zwingend erfordert, die Grösseninformation zu
ignorieren.
Es scheint mir ein Widerspruch zu bestehen:
Im Fall einer definierten auto-Variable (also das Beispiel mit einem
definierten Array in main) wird es ja auch als Zeiger behandelt und
die Grösseninformation erhalten. (Ich meine damit, dass lediglich
Ausdrücke mit Zeigern oder Element-Indexierung [was ja auf Zeiger
zurückzuführen ist] möglich sind. Das Array als Ganzes wiederum muss
bzw. kann nur als Zeigeroperand erscheinen.
Es sind in C gar keine Operanden möglich, die ein Array als Ganzes
behandeln - mit einer Ausnahme! Nämlich eben "sizeof" (OK. OK. Abgesehen
von align-Dingsbums :-) ).
Wenn das so ist, dann ist die Aussage, dass es auf das Vorhandensein der
Grössenangabe ankommt nicht falsch und nicht zu kurz gedacht.
Es scheint mir möglicherweise eine Fehldeutung des Standards darin zu
liegen, dass sich die Umwandlung von Arrays in Zeiger mit Verlust der
Grösseninformation, während der Kompilierungszeit, in dem einen Fall auf
auto-Variablen nicht bezieht, in dem anderen Fall eines Parameters
aber doch . Jedenfalls steht das nirgendwo ausdrücklich, meine ich.
Oder ich habe was übersehen.
Was meinst Du dazu?
Was ist denn deine Deutung des Standards? Dass Pointer die
Größeninformation doch erhalten (dürfen)? Wie kommt man denn laut
Standard an die Größe dran, denn sizeof(Pointer) soll ja die Größe des
Pointers selbst liefern. Nirgendwo im Standard steht dass Pointer eine
Array-Größe speichern, deshalb geht bei der Konvertierung nunmal
zwangsweise etwas verloren. Solange man das Array in der main() weiter
verwendet, wird ja nichts konvertiert, und es geht nichts verloren. Die
Größeninformation ist hier aber nur dem Compiler bekannt und wird in den
sizeof()-Ausdruck eingesetzt; sie wird aber nicht zur Laufzeit irgendwo
vorgehalten.
Niklas G. schrieb:> Was ist denn deine Deutung des Standards? Dass Pointer die> Größeninformation doch erhalten (dürfen)? Wie kommt man denn laut> Standard an die Größe dran, ...
Darüber steht ja im Standard nichts. Das ist ein Implementierungsdetail
des Compilers.
Die Frage scheint ja zu sein, ob man die Kompilation als monolithischen
Prozess betrachtet. Ob es wahr ist, dass es einen Zeitpunkt resp. eine
Phase gibt bevor das array als Pointer behandelt wird und einen zu dem
das getan wird oder nicht.
Das erste scheint ja im Fall eines auto-Arrays, definiert innerhalb
einer Funktion der Fall zu sein. Denn es ist ja in diesem Fall möglich
sizeof durch die Grösse des Arrays zu ersetzen.
Falls ich aber das zweite für gegeben hallte, dann sollte es auch für
auto-Arrays nicht möglich sein, sizeof zu verwenden.
> ... denn sizeof(Pointer) soll ja die Größe des> Pointers selbst liefern.
Nicht im Falle eines auto-Arrays definiert innerhalb der Funktion.
> Nirgendwo im Standard steht dass Pointer eine> Array-Größe speichern, deshalb geht bei der Konvertierung nunmal> zwangsweise etwas verloren. Solange man das Array in der main() weiter> verwendet, wird ja nichts konvertiert, und es geht nichts verloren.
Da, wie ich oben schrieb sämtliche Ausdrück (abgesehen von sizeof) auf
Arrays als Pointer beruhen (wenn auch austauschbar mit arrays in
Index-Ausdrücken), muss ja in einer Phase die Länge vorhanden sein,
während sie es in einer nachfolgen Phase, bei der Umsetzung in
Assembler, nicht mehr sein muss. Die Ersetzung von sizeof ist ja dann
schon erledigt.
Die Grössenangabe bei auto-Arrays wird ein Teil eines Tupels im
Syntaxbaum sein. Das aber geht auch für Parameter so. Meinst Du nicht?
Kurz gesagt: Es ergibt sich aus dem Standard und auch meiner Deutung
davon nicht, dass es in dem einen Fall geht und in dem anderen Fall
nicht geht oder nicht gehen darf. In beiden Fällen sind die
Größenangaben vorhanden.
> Die> Größeninformation ist hier aber nur dem Compiler bekannt und wird in den> sizeof()-Ausdruck eingesetzt; sie wird aber nicht zur Laufzeit irgendwo> vorgehalten.
Ich weiss nicht worauf Du damit hinaus willst. Das das zur Laufzeit noch
vorhanden ist oder sein muss, habe ich gar nicht behauptet. Es ergibt
sich auch aus meinen Einwänden nicht.
Theor schrieb:> Nicht im Falle eines auto-Arrays definiert innerhalb der Funktion.
Das ist ja auch ein Array und kein Pointer. sizeof-Ersetzung passiert
halt bevor der Compiler aus Arrays Pointer(-Arithmetik) macht.
Theor schrieb:> muss ja in einer Phase die Länge vorhanden sein,> während sie es in einer nachfolgen Phase, bei der Umsetzung in> Assembler, nicht mehr sein muss. Die Ersetzung von sizeof ist ja dann> schon erledigt.
Ja.
Theor schrieb:> Die Grössenangabe bei auto-Arrays wird ein Teil eines Tupels im> Syntaxbaum sein.
Ja.
Theor schrieb:> Das aber geht auch für Parameter so. Meinst Du nicht?
Wie denn? Im Syntaxbaum steht "Funktion MinMaxDurch hat Parameter vom
Typ double*". Da ist keine Größenangabe bekannt. Wo soll die herkommen?
Die Funktion wird ja ggf. von verschiedenen Dateien aus aufgerufen, wo
überall Pointer auf unterschiedlich große Speicherbereiche übergeben
werden könnten.
Der Compiler betrachtet jede Funktion für sich; beim Kompilieren von
MinMaxDurch weiß er nicht, mit welchen Array-Größen sie aufgerufen wird.
Oder wie meinst du das?
Theor schrieb:> In beiden Fällen sind die> Größenangaben vorhanden.
Die Größenangabe kommt erst beim tatsächlichen Aufruf der Funktion aus
einer bestimmten Stelle zustande. Die kann aber variabel sein, landet
also nicht im Syntaxbaum.
Theor schrieb:> Da, wie ich oben schrieb sämtliche Ausdrück (abgesehen von sizeof) auf> Arrays als Pointer beruhen
Ein ausserhalb der Parameterliste deklariertes Array ist zunächst vom
Typ her kein Pointer, sondern ein Array und behält daher eine ggf
bekannte Grösse. Erst in Expressions wird es ggf zum Pointer.
C11 6.3.2.1.3: "Except when it is the operand of the sizeof operator,
the _Alignof operator, or the unary & operator, or is a string literal
used to initialize an array, an expression that has type ‘‘array of
type’’ is converted to an expression with type ‘‘pointer to type’’ that
points to the initial element of the array object and is not an lvalue."
> Kurz gesagt: Es ergibt sich aus dem Standard und auch meiner Deutung> davon nicht, dass es in dem einen Fall geht und in dem anderen Fall> nicht geht oder nicht gehen darf. In beiden Fällen sind die> Größenangaben vorhanden.
Ein Array in einer Parameterdeklaration wird hingegen bereits per
Deklaration zum Pointer, nicht erst bei der Verwendung. Damit geht die
Information über die Grösse des Arrays verloren.
C11 6.7.6.3.7: "A declaration of a parameter as ‘‘array of type’’ shall
be adjusted to ‘‘qualified pointer to type’’, ..."
Da sizeof(Pointer) die Grösse eines Pointers angibt und in der
Definition von sizeof kein entsprechender Sonderfall aufgeführt wird,
ist die Sache damit geklärt. Egal wie man in der Parameterdeklaration
ein Array reinschreibt, bei sizeof gibts die Grösse des Pointers, nicht
die des Arrays.
Ob man das als sinnvoll betrachtet, oder ob die Information eigentlich
vorhanden wäre, interessiert den Standard nicht. Altlast.
Niklas G. schrieb:> Theor schrieb:>> Nicht im Falle eines auto-Arrays definiert innerhalb der Funktion.>> Das ist ja auch ein Array und kein Pointer. sizeof-Ersetzung passiert> halt bevor der Compiler aus Arrays Pointer(-Arithmetik) macht.
Lassen wir das mal (wenigstens zeitweise) aussen vor und kommen darauf
zurück. OK?
> [...] (Gekürzt wegen Übereinstimmung in diesem Punkt).>> Theor schrieb:>> Das aber geht auch für Parameter so. Meinst Du nicht?> Wie denn? Im Syntaxbaum steht "Funktion MinMaxDurch hat Parameter vom> Typ double*". Da ist keine Größenangabe bekannt. Wo soll die herkommen?
Das muss aber vom Standpunkt des Compilerimplementierers nicht
zwingend so sein. Er könnte sich genauso gut entscheiden im Syntaxbaum
auch die Grössenangabe eines als Parameter deklarierten Arrays zu
speichern. Was spricht dagegen? Nur die willkürliche Voraussetzung ,
dass während der Baum gebaut wird, alle array-parameter grundsätzlich
als Zeiger betrachtet werden. Hingegen beim parsen von Code der
innerhalb einer Funktion ein auto-Array enthält ist das nicht der Fall.
Wieso?
> Die Funktion wird ja ggf. von verschiedenen Dateien aus aufgerufen, wo> überall Pointer auf unterschiedlich große Speicherbereiche übergeben> werden könnten.
Das ist mein Einwand oben gegen meine eigene Ansicht gewesen. Siehe:
Beitrag "Re: C sizeof Funktion in main vs in Funktion"
Nur das ich das eben nicht mehr für stichhaltig halte.
Falls ich eine Funktion haben will, die Arrays als Parameter enthalten
soll und ich diese Funktion an verschiedenen Stellen mit Arrays
verschiedener Länge aufrufen will, steht es mir ja frei dies
ausdrücklich zuzulassen und zu schreiben:
1
funktion(TypName[],...)
oder
1
funktion(Typ*Name,...)
(Mit der Konsequenz dass ich sizeof ganz zweifelsfrei nicht verwenden
kann).
Schreibe ich hingegen
1
funktion(TypName[Laenge],...
dann ist das semantisch ganz präzise zu interpretieren: Die Funktion
kann ausschliesslich mit Arrays bestimmter Länge als Parameter
aufgerufen werden. Was mir überhaupt der Sinn zu sein scheint, die
Längenangabe syntaktisch zuzulassen. Oder gibt es einen anderen?
> [...]> Theor schrieb:>> In beiden Fällen sind die>> Größenangaben vorhanden.> Die Größenangabe kommt erst beim tatsächlichen Aufruf der Funktion aus> einer bestimmten Stelle zustande. Die kann aber variabel sein, landet> also nicht im Syntaxbaum.
Moment. Ist das ein Mißverständnis? Ich meine die folgenden beide Fälle.
1
funktion(....)[
2
TypName[Laenge];/* was ich im Thread als "definiertes auto-Array" bezeichne */
3
...
und
1
funktion(TypName[Laenge],...
Im der zweiten Variante ist die Länge nicht erst beim Aufruf bekannt,
sondern schon bei der Definition (und bei einer evtl. Deklaration).
Also ist in beiden Fällen die Grössenangabe vorhanden.
Theor schrieb:> Er könnte sich genauso gut entscheiden im Syntaxbaum> auch die Grössenangabe eines als Parameter deklarierten Arrays zu> speichern.
Die Syntax selbst ist die falsche Stelle. Diese Angabe geht verloren,
wenn im Rahmen der Abarbeitung einer Deklaration die Typ-Spezifikation
des Parameternamens erzeugt wird.
> Was spricht dagegen?
Der C-Standard. Und der definiert es so, weil es immer so war. Es gibt
nicht viele Fälle, in denen ein C Standard zu einem früheren Standard
(echt oder de fakto) inkompatibel wird.
Theor schrieb:> Moment. Ist das ein Mißverständnis? Ich meine die folgenden beide Fälle.
Ach! Dann ist das was anderes. Man hat sich vermutlich aus Gründen der
Kompatibilität dazu entschieden, dass Array-Parameter mit Größenabgabe
auch nur als Pointer behandelt werden, denn es wird ja letztlich auch
nur ein Pointer übergeben. Ich weiß jetzt nicht wo das im Standard
steht, aber wenn es falsch interpretiert wird würde das heißen dass
etablierte Compiler wie GCC hier falsch liegen - unwahrscheinlich
Niklas G. schrieb:> Theor schrieb:>> Moment. Ist das ein Mißverständnis? Ich meine die folgenden beide Fälle.>> Ach! Dann ist das was anderes. Man hat sich vermutlich aus Gründen der> Kompatibilität dazu entschieden, dass Array-Parameter mit Größenabgabe> auch nur als Pointer behandelt werden, denn es wird ja letztlich auch> nur ein Pointer übergeben. Ich weiß jetzt nicht wo das im Standard> steht, aber wenn es falsch interpretiert wird würde das heißen dass> etablierte Compiler wie GCC hier falsch liegen - unwahrscheinlich
Was ich meine und woraus ich das ableite, ist vielleicht etwas
kompliziert oder ich drücke mich nicht prägnant genug aus.
Was ich sagen will, ist dass eine zweite Deutung gibt, die auch nicht im
Widerspruch zum Standard steht.
Die Fussnote
"(105) When applied to a parameter declared to have array or function
type, the sizeof operator yields the size of the adjusted
(pointer) type (see 6.9.1)." [aus dem C17_proposal, aber die Fussnote
taucht auch in früheren Standards auf]
kann so interpretiert werden, dass sie sowohl 1. für die Phase des
Aufbaus des Syntaxbaumes gilt und für den Ersatz von sizeof durch die
angegebene Länge, als auch 2. für die Codesynthese.
Ich meine aber, es würde keinerlei Widersprüche mit der restlichen
Semantik und dem Standard aufwerfen, wenn sizeof auf array-Parameter mit
expliziter Längenangabe anwendbar wäre, so das es genau diese
Längenangabe schon während der Phase des Syntaxbaumaufbaus und Ersatz
ergibt.
Was bis dahin nicht ersetzt werden konnte, bleibt ohnehin nur als Zeiger
zu deuten und sizeof ergäbe folgerichtig die Grösse des Zeigertypen.
Dafür, dass es diesen Unterschied in den Compilerimplementierungn gibt
spricht, dass im Falle von auto-Arrays ja gerade das Array nicht als
Pointer interpretiert wird, und der Ersatz geschieht. Während der ersten
Phase des Aufbaus des Syntaxbaums wird die Grössenangabe in sizeof auf
das Array und nicht auf den Zeigertyp bezogen.
Der Unterschied beruht ja vom Standard aus nur auf dem "Parameter sein"
und darauf, dass die Compilation von den Implementierern in dem einen
Fall als homogener Prozess angesehen wird (bei der Parameterbehandlung;
aha, ein Pointer) anderseits aber als heterogener (bei den auto-Arrays;
aha, erstmal ein Array mit Grösse für sizeof, dann aber ein Pointer).
Ich hoffe das ist jetzt etwas prägnanter ausgedrückt.
Oder noch anders: Wenn sizeof technisch gesehen auf Parameter arrays mit
Längenangabe anwendbar ist, dann schränkt die Fussnote die Anwendung von
sizeof unnötig ein.
Es wäre hinreichend, wenn die Einschränkung nur für "incomplete types"
von Arrays in Parametern gelten würde.
Diese Einschränkung gilt ja ohnehin auch für definierte Zeiger bzw.
innerhalb von Funktionen.
1
funktion()[
2
inta[];
3
int*b;
4
...
ist es ja auch und ganz folgerichtig so, dass sizeof die Grösse des
Zeigertyps ergibt.
Theor schrieb:> Ich hoffe das ist jetzt etwas prägnanter ausgedrückt.
Prägnant, aber falsch.
Theor schrieb:> Oder noch anders: Wenn sizeof technisch gesehen auf Parameter arrays mit> Längenangabe anwendbar ist, dann schränkt die Fussnote die Anwendung von> sizeof unnötig ein.
Man hätte C anfangs anders definieren können, oder später inkompatibel
zu früher. Hat man aber nicht.
Theor schrieb:> Falls ich eine Funktion haben will, die Arrays als Parameter enthalten> soll und ich diese Funktion an verschiedenen Stellen mit Arrays> verschiedener Länge aufrufen will, steht es mir ja frei dies> ausdrücklich zuzulassen und zu schreiben:>>
C, Zeiger, Arrays, Sizeof....eine Thematik die wohl in semtlichen
Sparten die Leute beschäfftigt...
https://lkml.org/lkml/2015/9/3/428
..Linus of it´s finest,freundlich wie man ihn eben kennt regt er sich
auch über das sizeof Problem auf.