Boost logo

Boost Users :

Subject: [Boost-users] [extension]: g++ '-O2' optimization w/ type_map access thru member template function
From: Jeffrey Chang (jeffrey8chang_at_[hidden])
Date: 2009-04-10 12:59:30


Hi,

I'm a happy user of boost::extension library. Thanks Jeremy Pack et al. for
this great work, and hope it'll be accepted by Boost soon. My extension
library is dowloaded from http://boost-extension.blogspot.com/ (August 14,
2008 Link), which works great for me when compiled with "-O0" optimization
flag in g++ (my version: i686-apple-darwin9-g++-4.0.1).

But, when I compile with -O2 and access type_map object through member
template function, g++ seems to optimize away the initialization logic for
'type_map', and I'd get signal assertion of EXC_BAD_ACCESS. Here's my test
program:

 65 struct MyDict {
 66 boost::extensions::type_map mTypeDict;
 67 template< typename T >
 68 T & refInstance() { mTypeDict.get<T>(); }
 69 };
 70
 71 typedef std::set<int> IntSetType;
 72
 73 void test_MyDict_1_mem_data_access() {
 74 MyDict testObj;
 75 std::cout << "------ 1 " << std:: endl;
 76 IntSetType &rIntSet = testObj.mTypeDict.get<IntSetType>();
 77 std::cout << "------ 2 " << std:: endl;
 78 std::cout << "rIntSet.size() is " << rIntSet.size() <<
std::endl;
 79 std::cout << "------ 3 " << std:: endl;
 80 rIntSet.insert (123);
 81 std::cout << "------ 4 " << std:: endl;
 82 std::cout << "rIntSet.size() is now " << rIntSet.size() <<
std::endl ;
 83 std::cout << "------ 5 " << std:: endl;
 84 }
 85
 86 void test_MyDict_2_mem_func_access() {
 87 MyDict testObj;
 88 std::cout << "====== 1 " << std:: endl;
 89 IntSetType &rIntSet = testObj.refInstance<IntSetType>();
 90 std::cout << "====== 2 " << std:: endl;
 91 std::cout << "rIntSet.size() is " << rIntSet.size() <<
std::endl;
 92 std::cout << "====== 3 " << std:: endl;
 93 rIntSet.insert (123);
 94 std::cout << "====== 4 " << std:: endl;
 95 std::cout << "rIntSet.size() is now " << rIntSet.size() <<
std::endl ;
 96 std::cout << "====== 5 " << std:: endl;
 97 }

This test program runs without any problem when compiled with "-O0"; but
with "-O2" compiler flag, "test_MyDIct_1_mem_data_access()" is still run ok
as expect, but "test_MyDict_2_mem_func_access()" halts at line 93. Here's
the output when run under gdb:

------ 1
------ 2
rIntSet.size() is 0
------ 3
------ 4
rIntSet.size() is now 1
------ 5
====== 1
====== 2
rIntSet.size() is 86
====== 3

Program received signal EXC_BAD_ACCESS, Could not access memory.
Reason: KERN_PROTECTION_FAILURE at address: 0x0000005e
std::_Rb_tree<int, int, std::_Identity<int>, std::less<int>,
std::allocator<int> >::insert_unique (this=0x56, __v=@0xbffff24c) at
testHpcDictByType.c:871
871 _Link_type __x = _M_begin();
(gdb)

So my question is, what's wrong with accessing boost::extension::type_map
through "MyDict::refInstance<T>()" here? In g++ "-O2" mode, why does the
direct access to "MyDict::mTypeDict" is ok, while "MyDict::refInstance<T>()"
is not ?

I'm not sure if this is a generic g++ optimization problem, or specific to
boost::extension library. But, for me, it seems to happen only for type_map
data structure, but not others.

Thanks for shedding any light on this.

--- Jeffrey



Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net