Ich arbeite an einem Schulprojekt, in dem ich viele der C-Bibliotheksfunktionen reproduzieren muss. Ich kämpfe nur mit einem bestimmten Aspekt davon.
Wenn Sie auf die man-Seite für memchr
schauen, werden Sie sehen, dass es eine const void *
als Eingabe benötigt und eine einfache void *
zurückgibt. Ich würde annehmen, dass sie irgendwo in der Funktion von const
auf nicht const
für die Rückgabevariable umwandeln.
Wenn ich das tue ( clang -Weverything +Werror
), kompiliert es nicht. Es funktioniert ohne das -Weverything
-Tag, aber ich würde es lieber verwenden, wenn es irgendwie möglich ist.
Gibt es einen "richtigen" Weg, dies zu tun?
Dieser Hack wird es tun. In der Praxis ist sizeof(void *)
gleich sizeof(size_t)
auf allen außer den obskursten Plattformen. Trotzdem würde ich davon abraten, dies zu verwenden. Sie sollten stattdessen -Weverything
löschen. Standard-C-Funktionen reichen bis 70 'zurück, und die ursprünglichen C-Compiler waren viel weniger streng als das heutige Clang oder GCC, mit allen aktivierten Warnungen. Die Tatsache, dass Sie in einigen von ihnen etwas "unsicher" finden, ist unvermeidlich.
Wie Sie richtig bemerkt haben, müssen einige C-Bibliotheksfunktionen das Argument const pointer verwenden, um das const
-Qualifikationsmerkmal für den Rückgabewert zu entfernen: memchr
, strchr
, strstr
usw. Andere Standardfunktionen speichern einen Zeiger auf Das Ende der analysierten Zeichenfolge in ein char **
, obwohl es in das Array zeigt, an das sie übergeben wurden. const char *
: strtol
, strod '...
Wenn Ihr Compiler dies in die Irre führt und Warnungen erzeugt, versuchen Sie, nach uintptr_t
zu casten, bevor Sie auf unsigned char *
umwandeln. Sie können auch union
mit beiden Zeigertypen verwenden.
Der C-Standard gibt memcpy
auf diese Weise an:
7.24.5.1 Die Funktion
memchr
Übersicht
%Vor%Beschreibung
Die Funktion
memchr
findet das erste Vorkommen vonc
(konvertiert inunsigned char
) in den ersten n Zeichen (jeweils interpretiert alsunsigned char
) des Objekts, auf dass
zeigt. Die Implementierung muss sich so verhalten, als ob sie die Zeichen sequenziell liest und stoppt, sobald ein übereinstimmendes Zeichen gefunden wird.Gibt
zurückDie Funktion
memchr
gibt einen Zeiger auf das gefundene Zeichen oder einen Nullzeiger zurück, wenn das Zeichen nicht im Objekt vorkommt.
Wenn Sie keine anderen Typen verwenden können, erhalten Sie möglicherweise eine Umwandlung als size_t
, um die Warnung des Compilers zu unterdrücken. Hier ist eine mögliche Implementierung:
Das Problem ist unerwünschte GCC-Stil (Clang enthalten) Diagnose ausgelöst durch die Option -Wcast-qual
an einem bestimmten Ort ( -Weverything
enthält -Wcast-qual
). Die Lösung besteht darin, nur -Wcast-qual
in nur diesen Ort zu deaktivieren.
Eine Umwandlung in einen Nicht-Zeiger-Typ und zurück zu einem Zeigertyp würde alle Arten von nützlichen Diagnosen im Großhandel blockieren und somit den Zweck von -Weverything
vereiteln.
#ifdef __GNUC__
ist für mehr Portabilität enthalten. Es ist bekannt, dass einige Compiler vor Pragmas warnen, die sie nicht erkennen, es sei denn, solche Pragmas sind #ifdef
out.