1

I have the following code on Godbolt https://godbolt.org/z/YfobsnMra

And the same code on my machine

#include <string>
#include <cstdio>

int main() {
    std::string s;
    s[-8] = 42;
    printf("size: %d\n",s.size());
}

While this code compiles, it does not run because it appears that an assert is failing:

g++ cursed.cpp -o cursed

/usr/src/debug/gcc-build/x86_64-pc-linux-gnu/libstdc++-v3/include/bits/basic_string.h:1221: 
std::__cxx11::basic_string<_CharT, _Traits, _Alloc>::reference 
std::__cxx11::basic_string<_CharT, _Traits, _Alloc>::operator[](size_type) [with _CharT = 
char; _Traits = std::char_traits<char>; _Alloc = std::allocator<char>; reference = char&; 
size_type = long unsigned int]: Assertion '__pos <= size()' failed.
[1]    31811 IOT instruction (core dumped)  ./cursed

If I run g++ -v I get the following output:

Using built-in specs.
COLLECT_GCC=g++
COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-pc-linux-gnu/12.2.0/lto-wrapper
Target: x86_64-pc-linux-gnu
Configured with: /build/gcc/src/gcc/configure --enable-languages=c,c++,ada,fortran,go,lto,objc,obj-c++,d 
--enable-bootstrap --prefix=/usr --libdir=/usr/lib --libexecdir=/usr/lib --mandir=/usr/share/man 
--infodir=/usr/share/info --with-bugurl=https://bugs.archlinux.org/ --with-build-config=bootstrap-lto 
--with-linker-hash-style=gnu --with-system-zlib --enable-__cxa_atexit --enable-cet=auto 
--enable-checking=release --enable-clocale=gnu --enable-default-pie --enable-default-ssp 
--enable-gnu-indirect-function --enable-gnu-unique-object --enable-libstdcxx-backtrace 
--enable-link-serialization=1 --enable-linker-build-id --enable-lto --enable-multilib 
--enable-plugin --enable-shared --enable-threads=posix 
--disable-libssp --disable-libstdcxx-pch --disable-werror
Thread model: posix
Supported LTO compression algorithms: zlib zstd
gcc version 12.2.0 (GCC) 

How can I get the same behavior as Godbolt where it outputs 42? What compiler configuration am I missing to have the same behavior as Godbolt.

Cedric Martens
  • 1,139
  • 10
  • 23
  • 2
    The program has **undefined behavior**. *"Undefined behavior means anything can happen including but not limited to the program giving your expected output. But never rely on the output of a program that has UB. The program may just crash."* – Jason Dec 05 '22 at 06:11
  • What is `s[-8]` supposed to be? – Jason Dec 05 '22 at 06:12
  • @JasonLiam did you even read my question? – Cedric Martens Dec 05 '22 at 06:12
  • Please reopen this question – Cedric Martens Dec 05 '22 at 06:12
  • I know this is undefined behavior, that's why I wrote this program. Godbolt outputs 42 on GCC 12.2 but my version of GCC lands on an assert. This question is about what GCC options godbolt uses, not the contents of my code – Cedric Martens Dec 05 '22 at 06:14
  • 2
    `/usr/src/debug` -- Assertions should only happen if you are running against a debug version of the runtime library. C++ should not check for an out-of-bounds access on optimized, non-debug builds. If you turned on optimization, i.e. `-O1`, `-O2`, etc. what results do you get? If you still get an assertion, that may indicate that your compiler toolset is not setup correctly, as again, an optimized build should never check boundary conditions when using `[]`. – PaulMcKenzie Dec 05 '22 at 09:09
  • @PaulMcKenzie, I'm getting the same result as godbolt now (42) with -O1 and 2. Although, on godbolt it also works if -O0, is there a way to have an -O0 build that uses a non-debug std runtime lib? – Cedric Martens Dec 05 '22 at 15:59
  • Not sure how to do that with godbolt, and my main development environment is Visual Studio, not g++, and in that environment, running a debug build automatically turns on the assertions. You will have to ask the man behind the godbolt curtain as to what is going on. – PaulMcKenzie Dec 05 '22 at 17:25

0 Answers0