"We are back" « oc.at

[C] warning: ISO C90 does not support ...

lama007 24.02.2009 - 15:31 5082 21 Thread rating
Posts

lama007

OC Addicted
Avatar
Registered: Mar 2002
Location: Austria
Posts: 851
Hi!

Code:
#define _GNU_SOURCE   
#include <stdio.h>   
#include <stdlib.h>   
   
int main( void )   
{   
    FILE *fp;   
    char *line = NULL;   
    size_t len = 0;  
    ssize_t read;  
  
    fp = fopen( "/etc/motd", "r" );  
    if ( fp == NULL)  
        exit( EXIT_FAILURE );  
  
    while ( ( read = getline( &line, &len, fp ) ) != -1 ) {  
        printf( "Retrieved line of length %zu:\n", read );  
        printf( "%s", line );  
    }  
  
    if ( line )  
        free( line );  
    exit( EXIT_SUCCESS );  
}

Wenn ich diesen Code kompiliere, bekomme ich diese Fehlermeldung:
"warning: ISO C90 does not support the ‘z’ printf length modifier"

- kann ich solche Meldungen ignorieren?
- gibt es einen Ersatz für "%zu"?
- warum wird hier exit und nicht return verwendet? ( man-getline-Beispiel )

semteX

begehrt die rostschaufel
Avatar
Registered: Oct 2002
Location: Pre
Posts: 14811
- warnings ignoriern is selten gut... vor allem wenn es dir sagt, dass der C90 Standard das ding ned kennt. ich kannte es auch ned

- strlen(line)

- ka, exit tut auch nix anders als das programm zu beenden.
Bearbeitet von semteX am 24.02.2009, 16:47

lama007

OC Addicted
Avatar
Registered: Mar 2002
Location: Austria
Posts: 851
für "%zu" habe ich einen workaround gefunden:

"printf( "Retrieved line of length %d:\n", (int) read );"

quilty

Ich schau nur
Avatar
Registered: Jul 2005
Location: 4202
Posts: 3118
bzgl. exit:

exit terminiert das programm egal was gerade los ist (zack, bumm, finster wirds)
return kehrt zum aufrufer zurück

entscheidend vor allem bei rekursion.

Nico

former person of interest
Registered: Sep 2006
Location: -
Posts: 4082
ist ja auch die main-function..danach wirds nunmal dunkel ;)

lama007

OC Addicted
Avatar
Registered: Mar 2002
Location: Austria
Posts: 851
Zu diesem Beispiel habe ich noch eine Frage:

Irgendwo habe ich gelesen, das getline() nicht zum Umfang von ANSI C gehört,
darum habe ich mir erwartet, dass ich beim Kompilieren mit den Optionen -ansi -pedantic eine Fehlermeldung bekomme.
Stimmen meine Erwartungen bezüglich dieser Optionen nicht oder gehört getline() doch zum Umfang von ANSI C?

Nico

former person of interest
Registered: Sep 2006
Location: -
Posts: 4082
1: #define _GNU_SOURCE
unterbindet wohl die fehlermeldung. gnu c hat die funktion, ansi c nicht

quilty

Ich schau nur
Avatar
Registered: Jul 2005
Location: 4202
Posts: 3118
Zitat von Nico
ist ja auch die main-function..danach wirds nunmal dunkel ;)

bei dem sample machts keinen unterschied, aber auch die main kann rein theoretisch rekursiv aufgerufen werden.

watchout

Legend
undead
Avatar
Registered: Nov 2000
Location: Off the grid.
Posts: 6845
Zitat von lama007
Zu diesem Beispiel habe ich noch eine Frage:

Irgendwo habe ich gelesen, das getline() nicht zum Umfang von ANSI C gehört,
darum habe ich mir erwartet, dass ich beim Kompilieren mit den Optionen -ansi -pedantic eine Fehlermeldung bekomme.
Stimmen meine Erwartungen bezüglich dieser Optionen nicht oder gehört getline() doch zum Umfang von ANSI C?
Wenn eine Funktion nicht zum ansi c90 standard gehört sollte dir dieser Aufruf ein Warning liefern (weil funktion undefined).
ein #define _GNU_SOURCE "deaktiviert" solche Warnings - man darf halt dann nicht vergessen dass ein solches Programm dann nicht mehr c90 kompatibel ist - es wird u.U. nicht mehr mit einer anderen Stdlib als der GNU C lib kompilierbar sein.
Normalerweise steht übrigens in den Manpages ob eine Funktion im c90 standard vorkommt, bzw. wenn es abweichende Implementierungen gibt (ganz am Ende meistens - "CONFORMING TO" o.Ä.)

In der Manpage vom getline steht übrigens:
Zitat
CONFORMING TO
Both getline() and getdelim() are GNU extensions. They are available since libc 4.6.27.

lama007

OC Addicted
Avatar
Registered: Mar 2002
Location: Austria
Posts: 851
Aha, und ich habe gleich nachgeschaut: wenn alles passt steht unter "CONFORMING TO" nur "C89, C99."


Zur Speicherbefreiung habe ich folgenden Satz gefunden:
"Falls ein Speicherbereich freigegeben wird, der nicht zuvor mit malloc(), calloc() oder realloc() alloziiert wurde, kann dies katastrophale Folgen haben."

in der man-page von getline steht:
"If *lineptr is NULL, then getline() will allocate a buffer for storing the line, which should be freed by the user program."

Muss man immer die man-pages der Funktionen studieren, um zu wissen, ob es free() braucht oder nicht?

Ringding

Pilot
Avatar
Registered: Jan 2002
Location: Perchtoldsdorf/W..
Posts: 4300
Zitat von lama007
Muss man immer die man-pages der Funktionen studieren, um zu wissen, ob es free() braucht oder nicht?

Ja.

COLOSSUS

Administrator
GNUltra
Avatar
Registered: Dec 2000
Location: ~
Posts: 12171
Es ist generell ratsam, bei jeder Funktion, die du nicht aus dem Effeff kennst, einen kurzen Blick ins Manual zu werfen. Mit dem richtigen Setup deines Editors (bzw. deiner IDE) ist das ja kein wirklich schlagender Zeitverlust.

watchout

Legend
undead
Avatar
Registered: Nov 2000
Location: Off the grid.
Posts: 6845
Zitat von lama007
Zur Speicherbefreiung habe ich folgenden Satz gefunden:
"Falls ein Speicherbereich freigegeben wird, der nicht zuvor mit malloc(), calloc() oder realloc() alloziiert wurde, kann dies katastrophale Folgen haben."
Wo hast du denn den Satz her? :eek: Hört sich ja nach Weltuntergang an...

Zitat
free() frees the memory space pointed to by ptr, which must have been returned by a previous call to malloc(), calloc() or realloc(). Otherwise, or if free(ptr) has already been called before, undefined behaviour occurs. If ptr is NULL, no operation is performed.
Sagt "man 3 free". Man könnte natürlich annehmen dass wenn dieses Problem im Programm einer Kernkraftwerks-Steuerung zuschlägt tatsächlich katastrophale Folgen entstehen könnten, aber ich halte das etwas weit hergeholt :p

lama007

OC Addicted
Avatar
Registered: Mar 2002
Location: Austria
Posts: 851
Der Satz steht hier:
http://openbook.galileocomputing.de...9.htm#Xxx999328

Kann man das so sagen: wenn ich keinen Speicher von Hand reserviere, brauche ich ihn normalerweise auch nicht selbst befreien, außer bei ein paar Funktionen?

watchout

Legend
undead
Avatar
Registered: Nov 2000
Location: Off the grid.
Posts: 6845
Zitat von lama007
wenn ich keinen Speicher von Hand reserviere, brauche ich ihn normalerweise auch nicht selbst befreien, außer bei ein paar Funktionen?
Sollst du eigentlich auch nicht, weil du ja nicht weißt was dann passiert.

Das ganze lässt sich oft recht leicht anstellen - initialisierst du zb. so einen Pointer mit NULL kannst du recht sicher davon ausgehen dass du gefahrlos free() aufrufen kannst, weil der Pointer ja dann entweder NULL ist oder auf einen passenden Speicherbereich zeigt.

Ein 2. call an free() ist dann natürlich wieder anstrengend, vor allem wenns dann mit signals losgeht - wo/wann wurde SIGXY called? vor oder nach dem free, etc. Das hat bei mir schon paarmal in :bash: geendet...
Kontakt | Unser Forum | Über overclockers.at | Impressum | Datenschutz