8

This program (compiled with 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;
}

when compiled with Clang or MSVS, prints:

allocate 4 bytes on heap

allocate 2016 bytes on heap

However, when compiled with GCC (Version 9.2.0 provided by MSYS on Windows) it only prints:

allocate 4 bytes on heap

I am aware of short string optimization in GCC/libc++, but aren't 2000 chars too many for a short string? Is it a matter of SSO at all?

Angle.Bracket
  • 1,438
  • 13
  • 29
  • Comments are not for extended discussion; this conversation has been [moved to chat](https://chat.stackoverflow.com/rooms/205929/discussion-on-question-by-angle-bracket-when-compiling-with-gcc-overloaded-new). – Samuel Liew Jan 14 '20 at 10:47

1 Answers1

4

It seems that GCC does not (or can't?) implement replacement of the global operator new and operator delete correctly when dynamic libraries are involved on Windows.

See bug reports e.g. 77726, 82122 and 81413.

In your case std::string's constructor and/or std::allocator<char>::allocate seem to be located in the standard library's dynamic library, so that the operator new it uses isn't being replaced correctly.

YSC
  • 38,212
  • 9
  • 96
  • 149
walnut
  • 21,629
  • 4
  • 23
  • 59
  • 1
    To further clarify: this behavior has only been observed when using GCC with libc++ on Windows provided by MSYS / MINGW. Every version of GCC/libstdc++ on Ubuntu I was able to test worked exactly like those programs compiled with Clang or MSVS. Moreover, it is clearly not a case of SSO when compiled with GCC, as `sizeof(str)` yields `32`. – Angle.Bracket Jan 14 '20 at 11:36
  • @Angle.Bracket Do you mean libstdc++ instead of libc++? – walnut Jan 14 '20 at 11:36
  • I guess its called libc++ in MINGW – Angle.Bracket Jan 14 '20 at 11:37
  • @Angle.Bracket libc++ usually refers to the standard library implementation of the LLVM project for clang. I don't think gcc is able to use it, mingw or not. But I may be wrong here. – walnut Jan 14 '20 at 11:38
  • @Angle.Bracket I guess you can verify whether you are using libstdc++ or libc++ using the answers [in this question](https://stackoverflow.com/questions/31657499/how-to-detect-stdlib-libc-in-the-preprocessor). – walnut Jan 14 '20 at 11:45
  • Just verified it: it's libstdc++ – Angle.Bracket Jan 14 '20 at 11:47