Casting Const zu nicht Const in c

8

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?

    
user1803425 04.06.2017, 16:06
quelle

3 Antworten

1

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.

%Vor%     
Piotr Olszewski 04.06.2017, 16:39
quelle
3

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 von c (konvertiert in unsigned char ) in den ersten n Zeichen (jeweils interpretiert als unsigned char ) des Objekts, auf das s zeigt. Die Implementierung muss sich so verhalten, als ob sie die Zeichen sequenziell liest und stoppt, sobald ein übereinstimmendes Zeichen gefunden wird.

     

Gibt

zurück      

Die 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:

%Vor%     
chqrlie 04.06.2017 16:17
quelle
0

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.

%Vor%

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.

    
n.m. 05.06.2017 06:51
quelle

Tags und Links