zotbar1234 Skrevet 5. juni 2009 Del Skrevet 5. juni 2009 Tror nok du misforstår her, under C90 så kunne man droppe deklarasjon av funksjoner, C99 åpner *eksplisitt* for kall av funksjoner hvis prototype er ukjent. Det er ikke rom for misforståelse her. Det *er* tillatt å kalle funksjoner uten en synlig prototype. (...) men merk her at dette ikke er kompatibelt med prototypen til malloc()! ... hvilket er komplett uvesentlig i dette tilfellet. Kallet er tillatt og vil ha den ønskede effekten, forutsatt at argumentlisten stemmer. *Dersom* man bruker en argumentliste som ikke er kompatibel med malloc sin, så faller kallet under kategorien av "undefined behaviour". Men igjen, dette er komplett uvesentlig for innvendingen min. Kallet er tillatt. Under C99 er denne implisitte deklarasjonen droppet, fordi det gjør det enklere å finne bugs, C99 Rationale sier (...) Igjen, komplett uinteressant i dette tilfellet. Kjernen til innvendingen min var at din irettesettelse var feil. Kall av non-variadic functions er tillatt uten synlig prototype. OK, jeg husket ikke riktig der, og blandet noe om på C90 og C99. Uansett, hvis return eller exit mangler under C90, så er exit status til programmet udefinert. Har du et sitat fra standarden som underbygger dette? Lenke til kommentar
kernel Skrevet 5. juni 2009 Del Skrevet 5. juni 2009 Tror nok du misforstår her, under C90 så kunne man droppe deklarasjon av funksjoner, C99 åpner *eksplisitt* for kall av funksjoner hvis prototype er ukjent. Det er ikke rom for misforståelse her. Det *er* tillatt å kalle funksjoner uten en synlig prototype. Beklager, men du tar jo feil. Har slått opp i C99 standarden og mer tydelig enn dette kan det nesten ikke sies J.2 Undefined behavior [...] — A function, object, type, or macro that is specified as being declared or defined by some standard header is used before any header that declares or defines it is included (7.1.2). Uansett, hvis return eller exit mangler under C90, så er exit status til programmet udefinert. Har du et sitat fra standarden som underbygger dette? Hvis noe ikke er definert, så er det litt vanskelig å finne en slik referanse. 2.1.2.2 Hosted environment [...] If the main function executes a return that specifies no value, the termination status returned to the host environment is undefined. Lenke til kommentar
zotbar1234 Skrevet 5. juni 2009 Del Skrevet 5. juni 2009 Tror nok du misforstår her, under C90 så kunne man droppe deklarasjon av funksjoner, C99 åpner *eksplisitt* for kall av funksjoner hvis prototype er ukjent. Det er ikke rom for misforståelse her. Det *er* tillatt å kalle funksjoner uten en synlig prototype. Beklager, men du tar jo feil. Har slått opp i C99 standarden og mer tydelig enn dette kan det nesten ikke sies J.2 Undefined behavior [...] — A function, object, type, or macro that is specified as being declared or defined by some standard header is used before any header that declares or defines it is included (7.1.2). Hmm... standardbiblioteket er altså spesialbehandlet. Der har jeg lært noe nytt. For alle de andre funksjonene gjelder påstanden min fremdeles (doit kan kalles før dens deklarasjon er synlig). Uansett, hvis return eller exit mangler under C90, så er exit status til programmet udefinert. Har du et sitat fra standarden som underbygger dette? Hvis noe ikke er definert, så er det litt vanskelig å finne en slik referanse. 2.1.2.2 Hosted environment [...] If the main function executes a return that specifies no value, the termination status returned to the host environment is undefined. Hva er effekten av å nå "}" i main ihht C90? Lenke til kommentar
kernel Skrevet 5. juni 2009 Del Skrevet 5. juni 2009 (endret) Hmm... standardbiblioteket er altså spesialbehandlet. Der har jeg lært noe nytt. For alle de andre funksjonene gjelder påstanden min fremdeles (doit kan kalles før dens deklarasjon er synlig). Vikrkelig? Les C99 Rationale en gang til: 6.5.2.2 Function calls [...] A new feature of C99: The rule for implicit declaration of functions has been removed in C99. removed, betyr fjernet! Dette er rimelig klart også: After issuing the diagnostic, an implementation may choose to assume an implicit declaration and continue translation in order to support existing programs that exploited this feature. så når funksjons deklarasjon mangler, så må det komme en feilmelding, og may sier at kompilatoren er fri til å avslutte. Hvorfor du kverulerer på dette skjønner jeg ikke, det å ignorere feilmelding av manglende funksjons prototyper, er helt på trynet, og slike uvaner bør man bli kvitt selv om man benytter C90. I C++ kreves dessuten funksjons prototyper også. $ cat decl_missing.c #include <stdio.h> int main(void) { foo(); return 0; } void foo(void) { printf("Hello world!\n"); } $ gcc -std=c99 decl_missing.c decl_missing.c: In function ‘main’: decl_missing.c:9: warning: implicit declaration of function ‘foo’ decl_missing.c: At top level: decl_missing.c:13: warning: conflicting types for ‘foo’ decl_missing.c:9: warning: previous implicit declaration of ‘foo’ was here noe slikt ville jeg aldri godkjent på en kode audit. Hva er effekten av å nå "}" i main ihht C90? en return... men av hvilken verdi sies det ikke noe om. At en implisitt exit(0) gjøres, er helt nytt i C99. Endret 5. juni 2009 av kernel Lenke til kommentar
kernel Skrevet 5. juni 2009 Del Skrevet 5. juni 2009 (endret) Til sammenlikning gies det ingen feilmeldinger her: $ cat decl_ok.c #include <stdio.h> void foo(void) { printf("Hello world!\n"); } int main(void) { foo(); return 0; } $ gcc -std=c99 decl_ok.c $ Endret 5. juni 2009 av kernel Lenke til kommentar
zotbar1234 Skrevet 5. juni 2009 Del Skrevet 5. juni 2009 Hmm... standardbiblioteket er altså spesialbehandlet. Der har jeg lært noe nytt. For alle de andre funksjonene gjelder påstanden min fremdeles (doit kan kalles før dens deklarasjon er synlig). Vikrkelig? Les C99 Rationale en gang til: Hva rationale sier er uinteressant. Det er standarden som definerer språket. Standarden tillater eksplisitt kall av funksjoner uten prototyper. så når funksjons deklarasjon mangler, så må det komme en feilmelding, og may sier at kompilatoren er fri til å avslutte. Ikke ihht standarden. Hva er effekten av å nå "}" i main ihht C90? en return... men av hvilken verdi sies det ikke noe om. At en implisitt exit(0) gjøres, er helt nytt i C99. Hva er den spesifikke ordlyden? (jeg har ikke en kopi av C90). Lenke til kommentar
kernel Skrevet 6. juni 2009 Del Skrevet 6. juni 2009 Hva rationale sier er uinteressant. Det er standarden som definerer språket. Standarden tillater eksplisitt kall av funksjoner uten prototyper. Det er WG14 som har skrevet Rationale, og det som står der er utdypende i forhold til å forstå standarden, ikke i konflikt med den. At en funksjons prototype mangler, er ikke det samme som at en deklarasjon av en funksjon mangler! *sukk* *SUKK* *SUKK* Hint: int foo(); så når funksjons deklarasjon mangler, så må det komme en feilmelding, og may sier at kompilatoren er fri til å avslutte. Ikke ihht standarden. Hvis du ser i forordet på C99 standarden, så står følgende 7 Major changes in the second edition included: [...] — remove implicit function declaration og at du ikke skjønner hva dette betyr, vil ikke endres om jeg siterer standarden X ganger. Hva er den spesifikke ordlyden? (jeg har ikke en kopi av C90). Beklager, men jeg gidder faktisk ikke det. At det er som jeg sier, er noe enhver regular i comp.lang.c kan bekrefte. Lenke til kommentar
kernel Skrevet 6. juni 2009 Del Skrevet 6. juni 2009 så når funksjons deklarasjon mangler, så må det komme en feilmelding, og may sier at kompilatoren er fri til å avslutte. Ikke ihht standarden. Dette er reinspikka tull, når implisitt deklarasjon av funksjoner er fjernet, så skjer følgende under kompilering 6.5.1 Primary expressions Syntax primary-expression: identifier constant string-literal ( expression ) Semantics An identifier is a primary expression, provided it has been declared as designating an object (in which case it is an lvalue) or a function (in which case it is a function designator).81) [...] 81) Thus, an undeclared identifier is a violation of the syntax. Altså, når deklarasjon mangler, så ser kompilator en syntaks feil, og slike feil krever en diagnose melding: 5.1.1.3 Diagnostics A conforming implementation shall produce at least one diagnostic message (identified in an implementation-defined manner) if a preprocessing translation unit or translation unit contains a violation of any syntax rule or constraint og hva en implementasjonen/kompilator gjør etter en syntaks feil, er en QoI sak, kompilator kan avslutte, eller fortsette. Lenke til kommentar
zotbar1234 Skrevet 6. juni 2009 Del Skrevet 6. juni 2009 At en funksjons prototype mangler, er ikke det samme som at en deklarasjon av en funksjon mangler! Ja, jeg innser at jeg blandet sammen en funksjonsdeklarasjon med en funksjonsprototype. Du hadde rett -- det kreves en funksjonsdeklarasjon for å kunne kalle en funksjon (det kreves fortsatt ikke en funksjonsprototype for å kunne kalle en funksjon, men det var ikke det jeg protesterte på heller, så det blir poengløst nå. Jeg tok soleklart feil da jeg sidestilte funksjonsdeklarasjon med funksjonsprototypen). Hva er den spesifikke ordlyden? (jeg har ikke en kopi av C90). Beklager, men jeg gidder faktisk ikke det. Ok, men da gidder du ikke det. Greit nok. Lenke til kommentar
kernel Skrevet 7. juni 2009 Del Skrevet 7. juni 2009 At en funksjons prototype mangler, er ikke det samme som at en deklarasjon av en funksjon mangler! Ja, jeg innser at jeg blandet sammen en funksjonsdeklarasjon med en funksjonsprototype. Du hadde rett -- det kreves en funksjonsdeklarasjon for å kunne kalle en funksjon (det kreves fortsatt ikke en funksjonsprototype for å kunne kalle en funksjon, men det var ikke det jeg protesterte på heller, så det blir poengløst nå. Jeg tok soleklart feil da jeg sidestilte funksjonsdeklarasjon med funksjonsprototypen). Det å misforstå noe som står i C99 standarden, er ikke uvanlig og dokumentet vil være ytterst forvirrende for den jevne C programmerer. C89/C90 standarden var langt mer lettlest. I C++ betyr int foo(); det samme som int foo(void); I C er det ikke slik, fordi pre-standard C manglet funksjons prototyper og man ønsket fortsatt at en ANSI C kompilator skulle takle gamle K&R C programmer. Altså, i C kan man deklarere funksjon uten prototype som int foo(); selv om for eksempel dette menes: int foo(double *); men dette er særs dårlig ide å gjøre i praksis, for det man gjør er å skrive gammeldags K&R C kode som helst burde vært forbudt, slik som er tilfelle i C++. Hadde det ikke vært for at det er såpass mye gammel C kode, så hadde man nok i C også innført kravet om at int foo(); betyr int foo(void); I C++ kreves en cast fra malloc, slik som i char *buffer = (char*) malloc(10); gjør man det samme i C90, så risikerer man å fjerne feilmelding fra kompilator: /* ugyldig program, stdlib header mangler, trenger ikke få feil ved kompilering */ int main(void) { char *buffer = (char *)malloc(10); /*UB*/ return 0; } fordi C90 kompilator gjør en implisitt deklarasjon av malloc() som extern int malloc(); og når man gjør en cast fra int til char *, så er resultatet et gyldig program sett fra C90 kompilatoren sin side. Dropper man imidlertid cast, så vil /* ugyldig program, stdlib header mangler, alltid feilmelding */ int main(void) { char *buffer = malloc(10); /* UB */ return 0; } alltid gi en feilmelding fra kompilatoren, fordi char * og int ikke er kompatible typer. Men, man må sette kompilator i standard modus, slik som i gcc -ansi program.c eller cl /Za program.c For orden skyld, korrekt C program er #include <stdlib.h> int main(void) { char *buffer = malloc(10); return 0; } og det er en fordel at C99 nå har fjernet støtten for K&R C programmer som manglet funksjons deklarasjoner. Hva er den spesifikke ordlyden? (jeg har ikke en kopi av C90). Beklager, men jeg gidder faktisk ikke det. Ok, men da gidder du ikke det. Greit nok. Sett fra C90 kompilatorens sitt ståsted, så er ikke dette et defekt program: #include <stdio.h> int main(void) { printf("Hello World!\n"); /*return 0;*/ } selv om exit status til programmet ikke er definert. Jeg ser at c.l.c regular Flash Gordon, har lagt ut en kopi av ANSI C draft som vi begge i sin tid fikk fra Dan Pop: http://flash-gordon.me.uk/ansi.c.txt så da kan du studere på egen hånd. Lenke til kommentar
Anbefalte innlegg
Opprett en konto eller logg inn for å kommentere
Du må være et medlem for å kunne skrive en kommentar
Opprett konto
Det er enkelt å melde seg inn for å starte en ny konto!
Start en kontoLogg inn
Har du allerede en konto? Logg inn her.
Logg inn nå