Home Dashboard Directory Help
Search

Visual Studio 2012; std::string; == not possible by j_froehl


Status: 

Closed


1
0
Sign in
to vote
Type: Bug
ID: 777370
Opened: 1/24/2013 3:04:07 AM
Access Restriction: Public
0
Workaround(s)
view
0
User(s) can reproduce this bug

Description

Using std::string, it is not possible to do a compare of strings with == or < or >.
Details
Sign in to post a comment.
Posted by Microsoft on 1/29/2013 at 1:42 PM
Hi,

Thanks for reporting this issue. I've resolved it as By Design because the behavior of our C++ Standard Library implementation here conforms to the Standard.

First, the test case in your "steps to reproduce" contains a typo:

C:\Temp>type meow.cpp
#include <string>
using namespace std:
void Test(void)
{
string s1("Hallo");
string s2("Test");
if ( s1 == s2 )
cout << "Strings are equal" ;
}

C:\Temp>cl /EHsc /nologo /W4 /MTd /c meow.cpp
meow.cpp
meow.cpp(2) : error C2143: syntax error : missing ';' before ':'
meow.cpp(2) : error C2059: syntax error : ':'
meow.cpp(8) : error C2065: 'cout' : undeclared identifier

When the typo is fixed, and <iostream> is included for cout and endl, it compiles and runs successfully:

C:\Temp>type purr.cpp
#include <iostream> // Added for cout and endl
#include <string>
using namespace std; // Changed ':' to ';'

void Test() { // Changed (void) to (), stylistic change only
    string s1("Hallo");
    string s2("Test");

    if (s1 == s2) { // Added braces, stylistic change only
        cout << "Strings are equal" << endl; // Added "<< endl" to improve output
    } else {
        cout << "Strings are NOT equal" << endl; // Added, because this will be called
    }
}

int main() { // Added
    Test();
}

C:\Temp>cl /EHsc /nologo /W4 /MTd purr.cpp
purr.cpp

C:\Temp>purr
Strings are NOT equal

As for your attached project, where you weren't including <string>, I can explain what the Standard says and what our implementation was doing. The Standard says that STL headers include each other in "unspecified" ways (unless otherwise noted; for example, C++11 now requires <iostream>, which provides cout, to also include <ostream>, which provides endl - in C++98 this was not guaranteed). If you write a source file that uses X without including the header that is supposed to provide X according to the Standard, you trigger undefined behavior - meaning that the Standard allows the implementation to do anything. It could totally fail to compile, or compile and work cleanly, or act strangely. In this case, you are required to include <string> in order to use std::string and all of its operators.

When you forget to include <string>, our implementation "acts strangely" for the following reasons. We define the std::basic_string class template and the std::string typedef in an internal header <xstring> which should never be included directly by users. Because many things throughout the Standard Library are required to take or return basic_string, many of our headers include <xstring> to get basic_string's definition.

However, while <xstring> defines basic_string, it does NOT define any operators (including op+ and op<). The public header <string> includes <xstring> and then defines these operators. We do this because two of those operators are op<< and op>> for iostreams, yet the iostreams headers have to mention basic_string. <xstring> exists to untangle this circularity: <xstring> defines basic_string only, the iostreams headers include <xstring> so they can mention basic_string, then <string> includes the iostreams headers (and <xstring>) so it can define the operators that need to mention both basic_string and iostreams in their signatures.

Note: Connect doesn't notify me about comments. If you have any further questions, please E-mail me.

Stephan T. Lavavej
Senior Developer - Visual C++ Libraries
stl@microsoft.com
Posted by Microsoft on 1/29/2013 at 12:50 AM
Thanks for your feedback.

We are rerouting this issue to the appropriate group within the Visual Studio Product Team for triage and resolution. These specialized experts will follow-up with your issue.
Posted by Microsoft on 1/24/2013 at 11:41 PM
Thank you for submitting feedback on Visual Studio and .NET Framework. In order to efficiently investigate and reproduce this issue, we are requesting additional information outlined below.

Could you please give us a demo project to demonstrate the issue so that we can conduct further research?

Please submit this information to us within 4 business days. We look forward to hearing from you with this information.

Microsoft Visual Studio Connect Support Team
Posted by j_froehl on 1/24/2013 at 4:37 AM
In the meanwhile I found *my* fault. I forgot the line #include <string>.

Strange enough that it was possible to use std::string, without including the include file.

My project was a MFC project for a single diaglog. Additional, I included <vector>, <list>, <map> and <algorithm>.

With that all, I could write:

void ltrim( std::string &csString, const std::string &csDelimiter = "\n\t " )
{
    auto i = csString.find_first_not_of( csDelimiter );
    if ( i == std::string::npos )
        csString.clear();
    else
        csString.erase( 0, i );
}

But I could not compare strings.

That means, that I got a strange compiler fault message, when I used

std::map<std::string, std::string>mapData ;

Hidden deep inside the error message there is the information, that "<" is not available for the left element ... or similiar.

So, the problem has nothing to do with "std::string", but that I could do something, but not all with "std::string".

Posted by Microsoft on 1/24/2013 at 3:50 AM
Thank you for your feedback, we are currently reviewing the issue you have submitted. If this issue is urgent, please contact support directly(http://support.microsoft.com)
Sign in to post a workaround.
File Name Submitted By Submitted On File Size  
MFCandSTL.zip (restricted) 1/28/2013 -