2

The code is attached as a picture for slightly easier viewing, but essentially this:

#include <iostream>

using namespace std;

int main() {
    string manu = "Lamborghini";
    const char *const c_manu = manu.c_str();

    string new_manu(c_manu);
    manu[0] = 'P';

    cout << c_manu << endl;
    cout << new_manu << endl;

}

Spits out:

Pamborghini
Lamborghini

This is what I was expecting.

However, if you create a new string from the string that the c_str points at like this:

#include <iostream>

using namespace std;

int main() {
    string manu = "Lamborghini";
    const char *const c_manu = manu.c_str();

    string new_manu(manu);
    manu[0] = 'P';

    cout << c_manu << endl;
    cout << new_manu << endl;

}

Then it spits out:

Lamborghini
Lamborghini

I'm using GCC with CLion, someone ran the exact same code in VSCode and got the expected results for both cases.

Windows 10 x64

CLion 2020.3.3

cygwin64 3.2.0

CMake 3.17.5

Make: make.exe

C Compiler: gcc.exe

C++ Compiler: c++.exe

(all three bundled with cygwin)

Weird new string bug in clion

Brian61354270
  • 8,690
  • 4
  • 21
  • 43
  • 2
    What C++ standard are you building against? Not C++11 or newer? – StoryTeller - Unslander Monica Apr 03 '21 at 21:41
  • 2
    I dont find a reference for this, but I think that the problem is, that c_manu is const and so the compiler is allowed to assume that the content will not change. – gerum Apr 03 '21 at 21:44
  • 3
    I'm guessing you're using a version of gcc (probably before version 5) which is using copy on write strings. Note that the value returned by `c_str` is only valid until the string changes or is destroyed do your code has undefined behaviour – Alan Birtles Apr 03 '21 at 21:56
  • I get the same first result for both cases using GCC 7.5.0 and GCC 10.1.0 on Ubuntu. Check your compiler and make sure you clean your project to avoid errors related to your IDE caching. – Hack06 Apr 03 '21 at 21:59
  • No repo link for clang and gcc - https://godbolt.org/z/jrs4x7Ks1 – Richard Critten Apr 03 '21 at 22:17
  • Hmmmm... cygwin says I have: gcc 10.2.0.1 I'll try invalidating cache. – Justin Kasowski Apr 03 '21 at 22:18
  • Invalidate/restarted, still bugging out on me. I'm kind of new to c++, the c++ version is determined by gcc right? – Justin Kasowski Apr 03 '21 at 22:33
  • If you are using an old standard it may still be doing "copy-on-write" (not allowed since C++11) have a read of https://stackoverflow.com/questions/12199710/legality-of-cow-stdstring-implementation-in-c11 Make sure your compilation line includes something like `-std=c++17` (or c++11, c++14) – Richard Critten Apr 03 '21 at 22:45
  • Reproduced with gcc 4.9.3 and C++03 - https://godbolt.org/z/KsaxrjEh5 and fixes in 5.1 IIRC gcc 4.9.3 was still using "copy-on-write". – Richard Critten Apr 03 '21 at 22:51
  • @RichardCritten gcc-10 defaults on c++14. This looks like a bug in the standard library. – n. m. could be an AI Apr 03 '21 at 23:17
  • It was c++14. I'm completely reinstalling everything. Did some reading on cygwin's webpage and it says not to install straight to C:/ because there's a high probability of corruption (and this is what I had done). – Justin Kasowski Apr 04 '21 at 01:27
  • Just for kicks, you could add an `assert(c_manu==manu.c_str());` both before and after creating `new_manu`, and again after assigning to `manu[0]`. – Mark Ransom Apr 04 '21 at 01:45
  • According to cppreference `manu[0] = 'P'` may invalidate `c_str`. In your first example it seems it didn't invalidate it, but in the second one it invalidate it. – Antonio Apr 04 '21 at 11:43
  • @Antonio been looking for that quote - can you link it for me – Richard Critten Apr 04 '21 at 11:45
  • 1
    @RichardCritten [here](https://en.cppreference.com/w/cpp/string/basic_string/c_str) (Oh, sorry, reading it again it seems I read it wrongly: it is written `excluding operator[]`, so my mistake) – Antonio Apr 04 '21 at 21:10
  • @Antonio thanks anyway - still trying to explain this / answer the question. – Richard Critten Apr 04 '21 at 21:17
  • https://gcc.gnu.org/onlinedocs/libstdc++/manual/using_dual_abi.html Maybe the default is to use the old ABI on your system? – Marc Glisse Apr 04 '21 at 21:29
  • I uninstalled everything and completely re-installed. I only have one c++ library that I know of, the one Jetbrains tutorial says to include with Clion. I can't figure out what's wrong. I'm not super familiar with cmake. I uploaded my whole project: https://github.com/justinkasowski/help/tree/master/cmake-build-debug-cygwin Any help is appreciated! – Justin Kasowski Apr 05 '21 at 21:54

0 Answers0