7

It looks like std::string is a header only file at Community/VC/Tools/MSVC/?/include/xstring, and all generated code should be included inside a build target.

If I'm correct, how does Microsoft guarantee that the next Visual Studio version doesn't change xstring and the std::string internal structure?

Update 1:

I got many downvotes for this question so let me explain why I decided to ask it.

I'm faced with strange crash, and I can not understand why this happen. I use latest Qt 5.13.0 (MSVC2017_x64) and also I have some external libraries compiled with Visual Studio 2017. All have /MDd, I checked this with dumpbin util.

When I try to run any code that invokes Qt library and std::string, I'm getting wrong result (and crash at the end).

Here is very simple example:

#include <QApplication.h>

int main(int argc, char** argv) {
    QString s1("Test");
    std::string s2 = s1.toStdString(); // here we have s2 variable with wrong internal structure
    return 0;
}

My idea was that QtCore DLL library has std::string with internal structure not compatible with std::string from Visual Studio 2017. But Qt was created with Visual Studio 2017 (maybe not same as my current Visual Studio, because there was several minor releases), so I decided to ask here if they are compatible or not.

Update 2:

Problem was in _ITERATOR_DEBUG_LEVEL. Looks like Qt was compiled with level 2 and all my external libraries and application were compiled with level 0.

This option affects internal structure of many C++ standard library classes and introduce such side effects. So when we are inside toStdString() and create std::string, we have level 2 and one internal structure. When we are in application code, we have level 0 and another internal structure. We assign object with one internal structure to object with another.

Anyway now I have better understanding of some internals.

John Tracid
  • 3,836
  • 3
  • 22
  • 33
  • Don't look at the internal structure, use the public description of it. std:: is standard C++ nothing VS-specific. – Dave S Jun 27 '19 at 17:11
  • Most implementations don't implement directly in the standard named header, this is in case things move around as they have before – Mgetz Jun 27 '19 at 17:11
  • 4
    You should rely on what the ISO C++ standard says std::string should be like. (if you dont feel like reading the standard, [this](https://en.cppreference.com/w/cpp/string/basic_string) should be good enough) – Borgleader Jun 27 '19 at 17:14
  • 4
    Why do you care? –  Jun 27 '19 at 17:14
  • I don't think that there is any guaranty that they will keep the internal implementation details the same in a new version of their compiler. – drescherjm Jun 27 '19 at 17:16
  • Related: https://stackoverflow.com/questions/31816095/why-should-i-not-include-bits-stdc-h – πάντα ῥεῖ Jun 27 '19 at 17:18
  • 3
    A lot of downvote but I can tell why I'm interesting. Imaging we compiled some code into DLL library with Visual Studio 14 and we use `std::string`. Now we want to use this library with Visual Studio 15 code and something was changed in `xstring` file. How we could guaranty that if we call function from that library and assign result to string in out code it will work? – John Tracid Jun 27 '19 at 17:20
  • 2
    Visual Studio 2015 to 2019 are binary compatible. https://learn.microsoft.com/en-us/cpp/porting/binary-compat-2015-2017?view=vs-2019 – drescherjm Jun 27 '19 at 17:22
  • 4
    `How we could guaranty that if we call function from that library and assign result to string in out code it will work?` -- this should be in the question itself, your actual question is something like "are std::string objects guaranteed to be binary compatible between different versions of VS?" (instead of implying that you're counting on specific implementations of the code). You might even want to delete this and try again. – Dave S Jun 27 '19 at 17:26
  • I too would upvote if you fixed the question by adding the missing details (I did not downvote you). As written, I feel the question itself (without comments) is not clear or useful to future SO readers. – Dave S Jun 27 '19 at 17:56
  • 4
    In full honesty, I first read this question with the impression that you weren't aware of the difference between the C++ Standard and Visual Studio. But if you rephrase it to clarify what you're looking for (i.e. binary compatibility, build system portability, stability of solution files through Visual Studio versions), this would immediately be a more interesting question. – alter_igel Jun 27 '19 at 17:56
  • 2
    This could also be a problem with `Qt`. – drescherjm Jun 27 '19 at 18:10
  • 1
    Agreed, QString s.toStdString(); might be generating something that doesn't match the binary format for any of Visual Studio 2015 - 2019. Qt being built using VS does not mean some low-level type conversion code in it uses MS' std::string correctly. A 2-step process of Qt string > C string > std::string might work. Also, you might add a Qt tag. – Dave S Jun 27 '19 at 18:26

2 Answers2

6

how does Microsoft guarantee that the next Visual Studio version doesn't change xstring and the std::string internal structure?

Because they make a decision to guarantee that, or to not guarantee that.

For example, Visual Studio 2015 to 2019 are binary compatible.

That's a decision that was made, to do that. The result, if what you say is true, is that some of the implementation specifics of std::string on that platform are frozen. This is not unusual for libraries. libstdc++'s std::list::size was non-compliant to C++11 for many years, because they could not add a needed member variable without breaking binary compatibility.

In short, this is basically a project management decision, and if they ever change the header in a way that breaks things, they will tell you that binary compatibility has been broken and you need to rebuild and relink things accordingly.

As for your Qt issue, it does smell like a binary compatibility issue. But you say that both Qt and your application have been built in Visual Studio 2017 with /MDd, which would appear to rule that out. I would ask the Qt community for further help, possibly with slightly more information about your environment and about where you obtained Qt. Also ensure that you're using the version of Qt that's intended — perhaps there are multiple installations? Which one's on your include path?

Lightness Races in Orbit
  • 378,754
  • 76
  • 643
  • 1,055
4

Is std::string header only in Visual Studio?

Not entirely, it also depends on parts of the Standard C++ library that are implemented in Microsoft's Visual C++ Runtime. Building a binary with MSVC requires the VC++ runtimes to be linked. Only static libraries may be built without linking to a runtime, and then you must be careful to include none of the headers that require the runtime.

Is the std::string header only in Visual Studio?

(I originally read the headline this way.)

std::string is part of the C++ standard. To use std::string on any platform that supports standard C++, you should use #include <string>. It is a standard header available with pretty much any C++ compiler.

Every compiler or platform may implement the standard in its own way though. For example with MSVC you can see that xstring is how Microsoft implements std::string under the hood. If you include xstring.h directly you are writing code that depends on the version of MSVC that provides that header. That code would not be portable to other compilers.

If I'm correct, how does Microsoft guarantee that the next Visual Studio version doesn't change xstring and the std::string internal structure?

Microsoft does not guarantee that the next Visual Studio version will have the same std::string internal structure. In the past the implementation of the standard library has changed with every VC++ runtime release, which is why Windows users end up having dozens of VC++ runtime versions installed in their Add/Remove programs list.

Thankfully Microsoft has given us a guarantee that Visual Studio 2015, 2017, and 2019 all use a binary-compatible C++ runtime. This means that binaries built using the standard library provided in Visual Studio 2015 are compatible with binaries built using 2017 and 2019 too. There is no guarantee (yet) that a future version of Visual Studio will not change the VC++ runtime implemenation again.

Romen
  • 1,617
  • 10
  • 26
  • _"If you include xstring.h directly you are explicitly declaring that your code depends on the version of MSVC that provides that header!"_ Missing the point, which is that `` may well do this too – Lightness Races in Orbit Jun 27 '19 at 17:42
  • 4
    @LightnessRacesinOrbit, The C++ standard guarantees that `` exists, the contents of that header are different between MSVC, GCC, and other compilers though. If you have code that contains `#include ` it will *only* compile on MSVC. – Romen Jun 27 '19 at 17:56
  • Again, nobody's suggesting that one should do that, and nobody's saying that they are. The point is that, as an include, even one that's _done for you_, its contents are compiled into your program. If you then runtime-link against an object that has similarly included a different version of that file, then you have problems. This is the fundamental basis of the notion of _binary compatibility_ which you ought to look up now. – Lightness Races in Orbit Jun 28 '19 at 09:42
  • @LightnessRacesinOrbit, I'm not sure what *your* point is, my answer addresses `std::string` being part of the C++ standard, in response to the headline of this question! *"Is std::string header only in Visual Studio?"*. I also answered the questions regarding binary compatibility between Visual Studio versions. I am aware that using different compilers leads to those binaries not being compatible and I don't see how my answer states anything contrary to that. – Romen Jun 28 '19 at 13:57
  • I directly quoted the text I was referring to, and gave a specific rebuttal of the point contained within it. I don't know how to be any clearer, sorry. – Lightness Races in Orbit Jun 28 '19 at 14:02
  • It looks like you've misread the title. It's not "is the `` header available only in Visual Studio?". It's "is `std::string` header-only in Visual Studio". The wording of the first sentence of the question body, plus the premise of the rest of it, confirms that :) Discussion about the standardness of `std::string` has nothing to do with the question. The binary compat part of your answer is correct and I never said it wasn't. – Lightness Races in Orbit Jun 28 '19 at 14:03
  • I did interpret it differently, I initially submitted an edit for the question that corrected several grammar and spelling errors so I could not be sure that the title wasn't missing a "the". I understand why you said "missing the point" now, but I still believe the second part of my answer adequately addresses the binary compatibility concerns. I could edit the first part to also add that the standard implementation is provided by the VC++ runtime, which is linked when you build with MSVC. – Romen Jun 28 '19 at 14:06
  • I agree the second part is spot on. I was literally only addressing the quoted part! That's why I quoted it ;) – Lightness Races in Orbit Jun 28 '19 at 14:15