Ich bin dabei, C. zu lernen. Ich habe eine Methode, die 3 Strings braucht und sie kombiniert, um etwas zu tun. Folgendes war meine erste Implementierung mit einem GCC-Compiler.
%Vor% Das funktioniert gut. Aber als ich das mit cc -Wall -pedantic -g foo.c -o foo
kompiliert habe, habe ich Warnungen wie ISO C90 forbids variable length array ‘combined’
bekommen. MSVC kompilierte diesen Code nicht. Der Code wurde wie folgt geändert:
Fragen
-Wall -pedantic
. Soll ich auch -ansi
verwenden? Was wären die äquivalenten Flags, die in MSVC verfügbar sind? Das funktioniert gut. Aber als ich das mit cc -Wall -pedantic -g foo.c -o foo kompilierte, fing ich an, Warnungen wie ISO C90 zu bekommen verbietet variable Längen-Array 'kombiniert'.
Versuchen Sie, mit -std=c99
-Option (gcc) zu kompilieren.
MSVC kompilierte diesen Code nicht. Der Code wurde wie folgt geändert:
Wenn Arrays variabler Länge nicht Teil des Standards sind, warum hat GCC das implementiert?
VLAs sind Teil von ISO C99 (gcc und g ++ (als Erweiterung) unterstützen VLAs). MSVC unterstützt immer noch nur C89.
Es wird erwartet, dass mein Code auf GCC und MSVC kompiliert wird.
Dann sollten Sie keine VLAs in Ihrem Code IMHO verwenden.
memset
ist zwar Zeitverschwendung, da es sowieso überschrieben wird (mach dein erstes strcat
zu einem strcpy
). Und Sie sollten immer überprüfen, ob malloc
NULL zurückgibt. Egal was!
malloc
die beste Wahl, insbesondere wenn Sie die kombinierte Zeichenkette zurückgeben möchten. -std=c89
-Flagge oder etwas ähnliches. In jedem Fall folgt MSVC nicht immer dem Standard: -) Ich würde mich für Folgendes entscheiden:
%Vor%oder, da Sie nichts mit der Zeichenkette tun, außer sie auszudrucken:
%Vor%: -)
Eine andere Strategie, die ich gesehen habe, ist die Strategie "nur allokieren, wenn du musst":
%Vor%verwendet den Stapelspeicher, wenn die kombinierte Zeichenfolge passt und weist nur dann Speicher zu, wenn dies nicht der Fall ist. Dies kann oft zu einer wesentlichen Verbesserung der Geschwindigkeit führen, wenn der Großteil der Strings weniger als die Grenze erreicht.
Arrays mit variabler Länge waren nicht Teil des ersten ISO-C-Standards (verschiedentlich als "C89", "C90" oder "ANSI C" bezeichnet). Sie sind jedoch Teil des neuesten ISO-C-Standards (bekannt als "C99").
GCC kann Ihren Code in verschiedenen Modi kompilieren, einschließlich "strict C90", "C90-mit-GNU-C-Extensions" und "C99" (obwohl es nicht vollständig implementiert C99, es ist nah genug für die meisten praktischen Zwecke).
GCC verwendet standardmäßig "C90-mit-GNU-C-Erweiterungen", weshalb Ihr Code ohne Beanstandungen kompiliert wird. Mit -pedantic
wird angegeben, dass alle erforderlichen Warnungen vom relevanten Standard (in diesem Fall C90) ausgegeben werden sollen. Eine solche Warnung wird von Ihrem Code benötigt. Wenn Sie GCC die -std=c99 -pedantic
-Flags geben, um sie gegen den C99-Basis-Standard zu kompilieren und alle erforderlichen Warnungen zu senden, wird Ihr Code korrekt kompiliert.
Wenn Sie sicherstellen möchten, dass Ihr Code mit dem Basis-C90-Standard kompatibel ist, verwenden Sie -std=c90 -pedantic
(oder -ansi -pedantic
: -ansi
ist ein Synonym für -std=c90
beim Kompilieren von C-Code). Beachten Sie, dass MSVC C99 nicht unterstützt.
Ein sehr gebräuchliches Idiom, um diese Probleme zu umgehen, ist es, den Anrufer den Speicher verwalten zu lassen. Anstatt also Speicher selbst zuzuordnen (entweder mit einem Array variabler Länge auf dem Stack oder mit malloc
oder etwas), erwarten Sie, dass der Aufrufer Speicher bereitstellt. Bedenken Sie Folgendes:
Der Vorteil dieses Ansatzes ist, dass foo
niemals leckt. Darüber hinaus kann der Aufrufer ein einfaches Stack-basiertes Array verwenden, falls es für ihn funktioniert. Wenn er die genaue Größe wissen möchte, kann er foo
aufrufen und NULL
als viertes Argument übergeben.
Tags und Links string c portability