Frage

Ich versuche cairomm für gtkmm auf Windows zu bauen mit mingw. Compilation Pausen bei einem Funktionsaufruf, die einen Parameter hat, der hat eine reinterpret_cast eines Bool auf einen void *.

cairo_font_face_set_user_data(cobj(), &USER_DATA_KEY_DEFAULT_TEXT_TO_GLYPHS, reinterpret_cast<void*>(true), NULL);

Dies ist, wo die Codeumbrüche und Grund „ungültig reinterpret_cast von Bool auf void *“. Warum ist das passiert, und wie kann ich diese Zeile ändern, um es zu kompilieren? Hilfe benötigen

War es hilfreich?

Lösung

Ich sehe diese Benutzerdaten und Sie haben die Kontrolle über das, was mit dem Wert, warf den Bool in einen int zuerst getan wird: reinterpret_cast<void *> (static_cast<int> (true)). Dadurch Sinn das macht die void * Parameter an die Stelle der Template-Funktionen in dieser ANSI-C-Bibliothek nimmt. Alles, was Sie brauchen, ist ein wahr / falsch Wert. So soll es keine Gefahr vorübergehend diese Codierung als Zeiger, solange es gut als solche dokumentiert ist. Wirklich, würden Sie dies besser dran. reinterpret_cast<void *> (1) oder reinterpret_cast<void *> (+true)

Andere Tipps

Es sieht aus wie es funktionieren sollte, entsprechend der Norm. Abschnitt 3.9.1-7 sagt Bool ist ein integraler Typ und 5.2.10-5 sagt ein Wert von Integral-Typ kann explizit in einen mit reinterpret_cast Zeiger umgewandelt werden. Es scheint, dass Ihr Compiler nicht vollständig Standard ist.

Könnten Sie mit dem Ändern des „true“ zu einem 1 weg? Konvertieren zwischen ganzen Zahlen und Zeigertypen ist eine alte und unehrenhafte Tradition in C und damit C ++, und es wäre überraschend, einen Compiler zu finden, die es nicht tun würden.

Oder, wenn Sie wirklich, wirklich das zu tun haben, versuchen (void *) wahr. Dann die Hände waschen.

reinterpret_cast ist ein schlechte Idee rel="nofollow. Bitte geben Sie uns mehr über das Problem Sie versuchen zu lösen, und vielleicht werden wir eine Lösung, ohne auf umdeuten finden. Warum wollen Sie bool konvertieren void *?

Die einzigen Compiler Ich habe, dass darüber beschwert ist GCC (MinGW mit GCC 3.4.5) - und ich bin mir nicht sicher, warum. Der Standard scheint klar zu zeigen, dies erlaubt ist:

  

3.9.1 Grundtypen

     

...

     

Typen Bool, char, wchar_t und die   mit und ohne Vorzeichen Integer-Typen sind   kollektiv integrale Typen genannt.

     

5.2.10 umdeuten Besetzung:

     

...

     

Ein Wert von Integraltyp oder   Aufzählungstyp kann explizit sein   umgewandelt in einen Zeiger.

Wie gesagt, Monjardin der Abhilfe die Verwendung reinterpret_cast<void *> (static_cast<int> (true)) oder reinterpret_cast<void *> (1) sind vernünftig Abhilfen.

Es schlägt fehl, da die Besetzung keinen Sinn macht - Sie einen boolean true / false Wert einnehmen, und bitten die compilre dies als Zeiger zu interpretieren, die in stumpfen Bedingungen ist ein Speicherplatz. Die beiden Arent auch nur entfernt verwandt sind.

eine neuere Version des Compilers Versuchen. Ich habe gerade getestet und diese Besetzung arbeitet auf mindestens gcc 4.1 und höher. Ich weiß nicht genau, wie gcc Versionen Karte zu mingw Versionen though.

In einigen Situationen ist es sehr wünschenswert, die Compiler zu haben, warnen oder Fehler auf Code wie reinterpret_cast<void*>(true), obwohl dieser Code scheinbar legal C ++. Zum Beispiel hilft es auf 64-Bit-Plattformen portieren.

Casting eine 64-Bit-Zeiger in einen integralen Typ, der kleiner ist als ein Zeiger (wie int oder bool) ist oft ein Fehler: Sie der Zeigerwert sind abgeschnitten. Darüber hinaus ist die C ++ Spezifikation nicht zu garantieren scheint, dass Sie direkt einen Zeiger in einen kleineren integralen Typ umwandeln können (Hervorhebung hinzugefügt):

  

5.2.10.4. Ein Zeiger kann explizit in jedem integralen Typ umgewandelt werden groß genug, um es zu halten . Die Abbildungsfunktion ist die Implementierung definiert.

Ebenso einen kleineren Integraltyp in einen 64-Bit-Zeiger Gießen (wie bei reinterpret_cast<void*>(true)) ist oft ein Fehler auch: der Compiler in dem Zeiger des oberen Bits mit etwas zu füllen ist; tut es Null-fill oder Vorzeichen erweitern? Es sei denn, Sie Low-Level-plattformspezifischen Code für Speicher gerade schreiben Mapped I / O-Zugriff oder DMA, Sie wollen in der Regel gar nicht, dies zu tun, wenn Sie etwas hacky tun (wie eine Boolesche in einen Zeiger zu stopfen ). Aber die C ++ Spezifikation scheint nicht andere über diesen Fall viel zu sagen, als dass es die Implementierung definiert (siehe Fußnote weggelassen):

  

5.2.10.5. Ein Wert von Integraltyp oder Aufzählungstyp kann explizit in einen Zeiger umgewandelt werden. *

     

Ein Zeiger auf eine ganze Zahl von ausreichender Größe umgewandelt (falls eine solche bei der Umsetzung vorhanden ist) und zurück zum gleichen Zeigertyp wird seinen ursprünglichen Wert hat; Zuordnungen zwischen Zeiger und Zahlen sind ansonsten die Implementierung definiert.

@monjardin vorgeschlagen reinterpret_cast<void*>(static_cast<int>(true)). Wenn der Ursprung des Fehlers die Nichtübereinstimmung zwischen dem Integraltypen der Größe und der Zeigergröße ist, dann wird diese Arbeit auf den meist 32-Bit-Plattformen (wo sowohl int und void* sind 32 Bits), aber nicht auf den meist 64-Bit-Plattformen (wobei int 32 Bits ist und void* beträgt 64 Bits). In diesem Fall sollte int in diesem Ausdruck mit einem Zeiger-Größe Integer-Typ wie uintptr_t oder DWORD_PTR (auf Windows) ersetzt arbeiten, da Konvertierungen zwischen bool und Zeiger-Größe ganzen Zahlen erlaubt sind, und so sind Konvertierungen zwischen Zeiger-sized ganzen Zahlen sind und Zeiger.

Spätere Versionen von GCC haben die folgenden Unterdrückung Warnung Optionen , aber nicht für C ++ :

  

-Wno-int-to-Zeiger-Cast (C und Objective-C nur)
  Unterdrückt Warnungen von Abgüssen zu Zeigerart einer ganzen Zahl von einer anderen Größe.

     

-Wno-pointer-to-int-Cast (C und Objective-C nur)
  Unterdrückt Warnungen von Abgüssen von einem Zeiger auf einen Integer-Typen mit einer anderen Größe.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top