Möchte ISO C90 einhalten, aber wie?
-
Hallo,
ich habe ein Programm und habe es soweit umgestellt, dass ich nun beim Kompilieren fast keine Warnungen mehr bekomme. Eine ist leider übrig geblieben, die ich auch gerne beseitigen würde. Der Kompilier meckert, dass mein Code nicht ISO C90 konform ist, da ich eine Variable deklariere nachdem schon Code geschrieben wurde. Wie kann ich dass in meinem konkreten Fall ab geschicktesten lösen?
Hier der betroffene Code-Schipsel:
Das Problem ist die Deklaration der String-Variable tempString[]. Diese Variable müsste ich ja eigentlich am Anfang deklarieren, doch zu diesem Zeitpunkt weiß ich noch nicht, wie groß der String sein soll.
void getOneRule(int ruleNumber) { char *ptr = procfs_buffer; int pos = 0; int i = 0; for(i=1;i<ruleNumber;i++) { pos=strcspn(ptr,";"); ptr = (ptr+pos+1); } pos = strcspn(ptr,";"); //violation of ISO C90 //warning: ISO C90 forbids mixed declarations and code char tempString[(pos+1)]; strncpy(tempString, ptr, (pos)); tempString[pos]='\0';
thx
-
Hallo,
du musst die Variable zu Beginn des Blocks deklarieren, wenn du im ISO C90 Mode kompilieren willst. Oder du aktivierst den C99 Modus bei deinem Compiler (-std=c99 bei gcc), dann kannst du es so lassen.
EDIT: In dem Zusammenhang sollte man vllt. noch erwähnen, dass ISO C90 == ANSI C89 ist, wobei das z.B. beim gcc alles unter den Begriff ansi fällt.
MfG
GPC
-
In ISO C90 müssen lokale Variablen am Anfang der Funktion deklariert werden. Erts dann darf Code folgen.
Zudem wäre char tempString[(pos+1)]; ein VLA (variable length array), welche auch erst ab C99 erlaubt sind.
Da musst den Code also etwas überdenken
-
wie wäre es mit malloc?
void getOneRule(int ruleNumber) { char *ma = NULL; ma = (char *) malloc((pos+1)* sizeof(char)); free(ma);
-
Cool,
habe gerade mein C Buch in der Hand und hatte auch überlegt es mit malloc() zu machen. ABER mein kleines Programm ist ein Kernelmodul! Was für eine Headerdatei brauche ich denn um malloc() verwenden zu können? stdlib.h oder? Ich glaube die kann ich im Kernelspace nutzen oder? Zumindest meckert der Kompiler.
-
Warum nicht einfach ein ausreichend großes lokales Array?
-
greif dir ein buch ueber kernel/linux systemprogrammierung?
-
slayer977 schrieb:
Cool,
habe gerade mein C Buch in der Hand und hatte auch überlegt es mit malloc() zu machen. ABER mein kleines Programm ist ein Kernelmodul! Was für eine Headerdatei brauche ich denn um malloc() verwenden zu können? stdlib.h oder? Ich glaube die kann ich im Kernelspace nutzen oder? Zumindest meckert der Kompiler.
Ja die stdlib.h -> http://de.wikibooks.org/wiki/C-Programmierung:_stdlib.h
Zum Kernelspace und Userspace .. keine Ahnung würde mich aber auch mal interessieren, denn in Kernelmodulen muss ja auch Speicher allokiert werden
-
evtl. noch alloca(). Ist aber nicht wirklich zu empfehlen (siehe manpage).
-
Wenn wir schon dabei sind...
In Wikipedia steht
In C ( anders als in C++) sollte man aber auf den cast verzichten, da dieser dann den Fehler verbirgt, welchen man bekommen könnte wenn man malloc() nicht Inkludiert hat.
Wie ist das zu verstehen?
-
ich glaube in C könnte
char *str = (char) malloc( 10 );
ohne bekanntsein der Funktion malloc( ) wie eine lokale Funktionsdefinition aussehen!?
Greetz, Swordfish
-
es gibt für den Kernelspace den Befehl kmalloc().
http://ezs.kr.hsnr.de/TreiberBuch/html/a9387.html
Habe es gerade mal in mein Programm verbaut. Mal schauen ob ich gleich nen Absturz erlebe
-
Hm,
mein Modul läuft einwandfrei, jedoch bekomme ich in der Logfile messages immer wenn kmalloc() benutzt wird Fehlermeldungen:
Debug: sleeping function called from invalid context at mm/slab.c:2126 Aug 9 21:16:31 slayer977 kernel: in_atomic():1, irqs_disabled():0 Aug 9 21:16:31 slayer977 kernel: [<c015c351>] __kmalloc+0x80/0x82 Aug 9 21:16:31 slayer977 kernel: [<e0a2346e>] getOneRule+0x2e/0x79 [s3] Aug 9 21:16:31 slayer977 kernel: [<e0a2368e>] firewalling+0xce/0x5d6 [s3] Aug 9 21:16:31 slayer977 kernel: [<c011be46>] __wake_up_common+0x39/0x59 Aug 9 21:16:31 slayer977 kernel: [<e0a23bc9>] main_hook+0x33/0x77 [s3] Aug 9 21:16:31 slayer977 kernel: [<c0313039>] nf_iterate+0x60/0x84 Aug 9 21:16:31 slayer977 kernel: [<c0328b46>] ip_rcv_finish+0x0/0x2ca Aug 9 21:16:31 slayer977 kernel: [<c0313312>] nf_hook_slow+0x4d/0xe6 Aug 9 21:16:31 slayer977 kernel: [<c0328b46>] ip_rcv_finish+0x0/0x2ca Aug 9 21:16:31 slayer977 kernel: [<c032882c>] ip_rcv+0x1a6/0x4c0 Aug 9 21:16:31 slayer977 kernel: [<c0328b46>] ip_rcv_finish+0x0/0x2ca Aug 9 21:16:31 slayer977 kernel: [<c0308e07>] netif_receive_skb+0x1cf/0x274 Aug 9 21:16:31 slayer977 kernel: [<c0308f13>] process_backlog+0x67/0xe4 Aug 9 21:16:31 slayer977 kernel: [<c030904b>] net_rx_action+0xbb/0x2bf Aug 9 21:16:31 slayer977 kernel: [<e08f58d4>] ppp_async_process+0x1e/0x61 [ppp_async] Aug 9 21:16:31 slayer977 kernel: [<c01282de>] __do_softirq+0x3e/0x8a Aug 9 21:16:31 slayer977 kernel: [<c0105c29>] do_softirq+0x3e/0x42 Aug 9 21:16:31 slayer977 kernel: ======================= Aug 9 21:16:31 slayer977 kernel: [<c01283a5>] local_bh_enable+0x7b/0x7d Aug 9 21:16:31 slayer977 kernel: [<c03051c2>] datagram_poll+0xc5/0xe3 Aug 9 21:16:31 slayer977 kernel: [<c0371552>] packet_poll+0xba/0x1ae Aug 9 21:16:31 slayer977 kernel: [<c025f7ba>] normal_poll+0xe5/0x143 Aug 9 21:16:31 slayer977 kernel: [<c0259f3d>] tty_poll+0x57/0x61 Aug 9 21:16:31 slayer977 kernel: [<c02fdcc1>] sock_poll+0x12/0x14 Aug 9 21:16:31 slayer977 kernel: [<c019396e>] do_select+0x219/0x4c2 Aug 9 21:16:31 slayer977 kernel: [<c01935c1>] __pollwait+0x0/0x96 Aug 9 21:16:31 slayer977 kernel: [<c0193e0e>] sys_select+0x1df/0x38d Aug 9 21:16:31 slayer977 kernel: [<c017b8d7>] vfs_write+0xb1/0x110 Aug 9 21:16:31 slayer977 kernel: [<c0103a51>] syscall_call+0x7/0xb
-
Ha!
Ich habe nun das eine Flag veändert nun nu wird nicht mehr gemeckert.
Hab's von GFP_KERNEL auf GFP_ATOMIC geändert. Ob es nun richtig ist, und ob es gut ist, dass ich keine Meldungen mehr bekomme. Wer weiß?So sieht nun meine Speicherreservierung aus:
dynamicArray = kmalloc((pos+1)*sizeof(char), GFP_ATOMIC);
Und dann einfach wieder freigeben:
kfree(dynamicArray);
-
slayer977 schrieb:
Ha!
Ich habe nun das eine Flag veändert nun nu wird nicht mehr gemeckert.
Hab's von GFP_KERNEL auf GFP_ATOMIC geändert. Ob es nun richtig ist, und ob es gut ist, dass ich keine Meldungen mehr bekomme. Wer weiß?Kommt darauf an was du machst.
GFP_KERNEL
Normale Allokation von Kernel-Speicher. Kann schlafen.GFP_ATOMIC
Wird dazu verwendet, Speicher aus Interrupt-Handlern und anderem Code außerhalb von Prozeß-Kontexten zu allozieren. Schläft nie.http://www.oreilly.de/german/freebooks/linuxdrive2ger/get.html
@Swordfish:
Habe sogar hier was zum Thema casten von malloc in C gefunden:
http://www.c-plusplus.net/forum/viewtopic-var-t-is-12864-and-start-is-0-and-postdays-is-0-and-postorder-is-asc-and-highlight-is-.html
-
Was nehme ich denn da am besten? Habe jetzt ATOMIC.
Was ich mache (vereinfacht) ist ich schaue in meinem ProcfsBuffer und suche nach dem ersten Auftauchen des Semikolons. Dann erzeuge ich diesen dynamicArray, der genau so lang sein soll, so dass alles von Anfang des Procfs Strings bis zum Semikolon da rein passt.Ist dafür ATOMIC nun gut?
-
codefrag schrieb:
@Swordfish:
Habe sogar hier was zum Thema casten von malloc in C gefunden:
http://www.c-plusplus.net/forum/viewtopic-var-t-is-12864-and-start-is-0-and-postdays-is-0-and-postorder-is-asc-and-highlight-is-.htmlJa, so meinte ich das
Greetz, Swordfish
-
wieso kompilierst du denn nicht einfach als c99? Oder hast du vor dein Linux-Kernel-Modul mit irgendwas anderem als gcc zu kompilieren?