$ cat t.cpp #include<string> int sain() { const std::string s("a"); return 0; } # gcc version 7.0.0 20170118 (experimental) (GCC) $ g++ -S -o t.s t.cpp -O2 -fno-exceptions -std=c++11 $ cat t.s .type _Z4sainv, @function _Z4sainv: .LFB940: .cfi_startproc pushq %rbx .cfi_def_cfa_offset 16 .cfi_offset 3, -16 movl $.LC0+1, %esi subq $32, %rsp .cfi_def_cfa_offset 48 leaq 16(%rsp), %rbx movq %rsp, %rdi movq %rbx, (%rsp) call _ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE12_M_constructIPKcEEvT_S8_St20forward_iterator_tag.isra.16.constprop.20 movq (%rsp), %rdi cmpq %rbx, %rdi je .L13 call _ZdlPv .L13: addq $32, %rsp .cfi_def_cfa_offset 16 xorl %eax, %eax popq %rbx .cfi_def_cfa_offset 8 ret .cfi_endproc .LFE940: .size _Z4sainv, .-_Z4sainv clang++, on the other hand, completely optimizes the const string. .type _Z4sainv,@function _Z4sainv: # @_Z4sainv .cfi_startproc # BB#0: xorl %eax, %eax retq .Lfunc_end0: .size _Z4sainv, .Lfunc_end0-_Z4sainv
Cannot reproduce. Try a more recent snapshot?
If you replace "a" with something longer (size>16 when counting the last '\0'), it does reproduce. I'd say this is a dup of 2 known issues: - the compiled part of libstdc++ prevents optimization (maybe eventually with LTO?), - gcc knows about malloc and free but not about new and delete. I didn't check if those are the only blockers in this case...
(In reply to Marc Glisse from comment #2) > I didn't check if those are the only blockers in this case... Looks like they are indeed the only blockers, since we optimize the below just fine. So, known issue (which doesn't mean we shouldn't do something about it). (with 2 dead strings instead of 1, we need -O3, -O2 is not sufficient) #include <bits/c++config.h> #undef _GLIBCXX_EXTERN_TEMPLATE #define _GLIBCXX_EXTERN_TEMPLATE 0 #include <string> #include <memory> inline void operator delete(void*p){__builtin_free(p);} inline void* operator new(size_t n){return __builtin_malloc(n);} int main() { const std::string s("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"); }
23383
Lets close as dup. *** This bug has been marked as a duplicate of bug 78104 ***
Reopening as it is not a dup of that one (though I think there is another bug about this one).
With -std=c++20 -O2 I get better code than just -std=c++17 -O2: _34 = operator new (24); __builtin_memcpy (_34, "a ", 23); MEM[(char_type &)_34 + 23] = 0; operator delete (_34, 24); That is all I think due to what is referenced in PR 86590.
(In reply to Andrew Pinski from comment #7) > With -std=c++20 -O2 I get better code than just -std=c++17 -O2: > _34 = operator new (24); > __builtin_memcpy (_34, "a ", 23); > MEM[(char_type &)_34 + 23] = 0; > operator delete (_34, 24); > > That is all I think due to what is referenced in PR 86590. Yes, it's because the explicit instantiations are disabled for C++20: # if __cplusplus <= 201703L && _GLIBCXX_EXTERN_TEMPLATE > 0 extern template class basic_string<char>;
can't repro this with gcc 12.1 Seems like this is fixed? https://godbolt.org/z/e6n94zK4E
(In reply to AK from comment #9) > can't repro this with gcc 12.1 Seems like this is fixed? No. As stated in other comments, it still reproduces with a longer string (or with -D_GLIBCXX_USE_CXX11_ABI=0).