Beim Kompilieren mit MINGW gcc wird ein überladener neuer Operator nicht für std :: string aufgerufen

8

Dieses Programm (kompiliert mit Option -std=c++17)

#include <stdio.h>
#include <string>
void* operator new(std::size_t nrOfBytes) {
    printf("allocate %zd bytes on heap\n", nrOfBytes);
    void* p = malloc(nrOfBytes);
    if (p) {
        return p;
    } else {
       throw std::bad_alloc{};
    }
}
int main() {
    // new operator is called when compiled with Clang or MSVS or GCC 
    int* i = new int;
    delete i;
    // new operator is not called when compiled with GCC
    // but is called with Clang and MSVS 
    std::string str(2000, 'x');
    return 0;
}

Beim Kompilieren mit Clang oder MSVS werden folgende Drucke erstellt:

Ordnen Sie 4 Bytes auf dem Heap zu

Ordnen Sie 2016 Bytes auf dem Heap zu

Beim Kompilieren mit GCC (Version 9.2.0 von MSYS unter Windows) wird jedoch nur Folgendes gedruckt:

Ordnen Sie 4 Bytes auf dem Heap zu

Ich bin mir der Optimierung kurzer Zeichenfolgen in GCC / libc ++ bewusst, aber sind 2000 Zeichen nicht zu viele für eine kurze Zeichenfolge? Geht es überhaupt um SSO?

Winkelträger
quelle
Kommentare sind nicht für eine ausführliche Diskussion gedacht. Dieses Gespräch wurde in den Chat verschoben .
Samuel Liew

Antworten:

4

Es scheint, dass GCC das Ersetzen des globalen operator newund operator deletekorrekten nicht implementiert (oder nicht?) Implementiert , wenn dynamische Bibliotheken unter Windows beteiligt sind.

Siehe Fehlerberichte, z. B. 77726 , 82122 und 81413 .

In Ihrem Fall befindet sich std::stringder Konstruktor und / oder std::allocator<char>::allocatescheint sich in der dynamischen Bibliothek der Standardbibliothek zu befinden, sodass die operator newverwendete Bibliothek nicht korrekt ersetzt wird.

Nussbaum
quelle
1
Zur weiteren Verdeutlichung: Dieses Verhalten wurde nur bei Verwendung von GCC mit libc ++ unter Windows von MSYS / MINGW beobachtet. Jede Version von GCC / libstdc ++ unter Ubuntu, die ich testen konnte, funktionierte genau wie die mit Clang oder MSVS kompilierten Programme. Darüber hinaus handelt es sich eindeutig nicht um SSO, wenn es mit GCC als sizeof(str)Ausbeute zusammengestellt wird 32.
Angle.Bracket
@ Angle.Bracket Meinst du libstdc ++ statt libc ++?
Walnuss
Ich denke, es heißt libc ++ in MINGW
Angle.Bracket
@ Angle.Bracket libc ++ bezieht sich normalerweise auf die Standardbibliotheksimplementierung des LLVM-Projekts für clang. Ich glaube nicht, dass gcc es benutzen kann, mingw oder nicht. Aber ich kann mich hier irren.
Walnuss
@ Angle.Bracket Ich denke, Sie können anhand der Antworten in dieser Frage überprüfen, ob Sie libstdc ++ oder libc ++ verwenden .
Walnuss