tags:

views:

972

answers:

3

After upgrading to XCode 3.2 and Snow Leopard, my debug builds are broken and fail at runtime. Stringstreams do not seem to work. They work in Release mode.

I've narrowed it down to a combination of GCC 4.2, OSX SDK 10.6 and the _GLIBCXX_DEBUG pre-processor symbol. These are the defaults for new XCode projects' Debug configurations.

This code shows the problem:

#include <iostream>
#include <string>
#include <sstream>

int main (int argc, char * const argv[]) {

 std::stringstream stream;
 std::cout << "             expected  actual" << std::endl;
 std::cout << "stream.bad:  0         " << stream.bad() << std::endl;
 std::cout << "stream.fail: 0         " << stream.fail() << std::endl;
 std::cout << "stream.eof:  0         " << stream.eof() << std::endl;
 std::cout << "stream.good: 1         " << stream.good() << std::endl;

 stream.exceptions(std::ios::badbit | std::ios::failbit | std::ios::eofbit);
 try{
  stream << 11;       //< Does not work as expected (see output)
 }catch (std::bad_cast &e) {
  std::cout << "Unexpected bad_cast: " << e.what() << std::endl;
 }catch(std::exception &e){
  std::cout << "Unexpected exception: " << e.what() << std::endl;
 }

 std::cout << "             expected  actual" << std::endl;
 std::cout << "stream.bad:  0         " << stream.bad() << std::endl;
 std::cout << "stream.fail: 0         " << stream.fail() << std::endl;
 std::cout << "stream.eof:  0         " << stream.eof() << std::endl;
 std::cout << "stream.good: 1         " << stream.good() << std::endl;
 std::cout << std::endl;
 std::cout << "EXPECT: " << 11 << std::endl;
 std::cout << "ACTUAL: " << stream.str() << std::endl;

 std::cout << std::endl << "Done" << std::endl;
 return 0;
}

The stringstream insertion should work, but when using GCC 4.2 and _GLIBCXX_DEBUG, the '<<' operator throws an exception, and the bad and fail bits are set.

I've tried various combinations of compiler and SDK with these results: - Using GCC 4.2, LLVM-GCC, or CLANG with SDK 10.6 does NOT work. - Using GCC 4.2, LLVM-GCC, or CLANG with SDK 10.5 does work. - Using GCC 4.0 with either SDK 10.5 or 10.6 works.

If _GLIBCXX_DEBUG is broken or not supported (with SDK 10.6 and GCC 4.2), then why is this the default for Debug configurations in new projects (C++ command line)?

+4  A: 

STL debug mode is not supported in gcc 4.2 at this time. You can use gcc 4.0 with STL debug mode, or remove the debug mode preprocessor macros from your Debug configuration and keep using gcc 4.2.

cdespinosa
Of course, since GCC is open source, you can always fix it yourself.
Crashworks
Thanks,Is this for Apple's GCC only? It works on other platforms with this version.If it is not supported, then why is it the default in XCode?Does Apple document this anywhere?
crmoore
A: 

Do not forget to configure each target if you have many (I had this problem) since the projet build config does not overwrite the target build config.

I really envoy finally finding out to fix this, I was using an XP VirtualMachine and Studio 2005 to avoid this problem!

jpdoyle
A: 

This is now a known and reported bug in the compiler. The only workarounds are:

  1. Remove the flags as you suggested. This is okay, but those flags are very useful at times, and you don't want to remove them from projects and after the bug is fixed go back and update them again!

  2. Execute in release mode for testing until you really need the debugger symbols and then temporarily remove the flags.

I have opted for #2 so that when the fix comes out, but projects are not missing the flags. For more information see:

Apple Discussions

BTW, the code the that I had that had this problem was just this simple:

#include <iostream>
#include <string>

using namespace std;

int main() {
    string firstName;
    string lastName;
    int age;
    char gender;

    cout << "Enter First Name: " << endl;
    cin >> firstName;  // <----- error happens right here

    cout << "Enter Last Name: ";
    cin >> lastName;

    cout << "Enter age: ";
    cin >> age;

    cout << "Enter gender: (m or f) ";
    cin >> gender;

    cout << firstName << lastName << age << gender;

    return 0;
}
CHardnett