This is the mail archive of the cygwin mailing list for the Cygwin project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: BUG REPORT: Cygwin, g++, -O2, static member function, std::string


This is a reply to the message
http://cygwin.com/ml/cygwin/2007-10/msg00509.html:

The linker is supposed to resolve a function-local static variable into one exactly one instance, constructed on the first call, even if the function is expanded in-line from multiple compilation units. It seems that the problem is not just multiple in-line expansions, but the fact that there is no obvious "home" compilation unit for this header-only class. The following variant on Brad's example shows this:

-------------- Cut Here test2.sh ---------------
#! /bin/bash
#
echo "A Cygwin g++ -O2 Bug Report:"
echo "RESULT: This slightly modified version works"
echo "SIDE EFFECTS: the files ./bug0.hpp, bug1.cpp, and bug2.cpp are created."
echo "RUN TEST: ./test2.sh"
#
cat << EOF > bug0.hpp
# include <string>
class Element {
public:
std::string file;
~Element();
static Element *root(void)
{ static Element r;
return &r;
}
};
EOF
cat << EOF > bug0.cpp
# include "bug0.hpp"
Element::~Element(){}
EOF
cat << EOF > bug1.cpp
# include "bug0.hpp"
extern void bug2(void);
int main(void)
{ std::string str("A");
char c = str[0];


   Element *r = Element::root();
   bug2();

   return 0;
}
EOF
cat << EOF > bug2.cpp
# include <cassert>
# include "bug0.hpp"
void bug2(void)
{
   Element *r = Element::root();
   Element *s = Element::root();

   assert( r != 0 );
}
EOF
echo "g++ bug1.cpp bug2.cpp bug0.cpp -O1 -o bug.exe"
g++ bug1.cpp bug2.cpp bug0.cpp -O1 -o bug.exe
echo "./bug"
./bug
echo "g++ bug1.cpp bug2.cpp bug0.cpp -O2 -o bug.exe"
g++ bug1.cpp bug2.cpp bug0.cpp -O2 -o bug.exe
echo "./bug"
./bug
-------------- Cut Here ---------------

Here, the offending function is still in-line and still invoked from two places, but I have added a destructor and implemented it in one place. That's enough to make it work.

It's still a bug in the linking process, in that it doesn't conform to the C++ standard. Brad's original version should have worked. Header-only libraries are very common, especially where templates are involved, so this is not unimportant.

By the way, it's not just a g++ problem. Brad's original code (minus .exe) runs just fine under Linux using an even older version of g++ (3.2.3 on my Linux, vs. 3.4.4 under Cygwin).

Bob Goddard


-- Unsubscribe info: http://cygwin.com/ml/#unsubscribe-simple Problem reports: http://cygwin.com/problems.html Documentation: http://cygwin.com/docs.html FAQ: http://cygwin.com/faq/


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]