Earlier today, gcc gave me a warning that I belive to be erroneous and now I am very unsure if it is an actual compiler bug(usually highly unlikely) or a bug in my code(usually highly likely). I managed to reduce it down to the following code:
#include <algorithm>
#include <array>
#include <iostream>
int main()
{
std::array<int,8> test{};
int valid = 0;
for(int i=0;i<8;++i)
{
if(i==0)
test[valid++] = 0;
}
// if(valid<8)
std::sort(test.begin(),test.begin()+valid);
}
Here it is on Compiler explorer
When compiled with optimization level -O2 or higher with gcc 12.1 or trunk, this warning about an out-of-bounds access is emitted:
In file included from /opt/compiler-explorer/gcc-12.1.0/include/c++/12.1.0/algorithm:61,
from <source>:1:
In function 'void std::__final_insertion_sort(_RandomAccessIterator, _RandomAccessIterator, _Compare) [with _RandomAccessIterator = int*; _Compare = __gnu_cxx::__ops::_Iter_less_iter]',
inlined from 'void std::__final_insertion_sort(_RandomAccessIterator, _RandomAccessIterator, _Compare) [with _RandomAccessIterator = int*; _Compare = __gnu_cxx::__ops::_Iter_less_iter]' at /opt/compiler-explorer/gcc-12.1.0/include/c++/12.1.0/bits/stl_algo.h:1844:5,
inlined from 'void std::__sort(_RandomAccessIterator, _RandomAccessIterator, _Compare) [with _RandomAccessIterator = int*; _Compare = __gnu_cxx::__ops::_Iter_less_iter]' at /opt/compiler-explorer/gcc-12.1.0/include/c++/12.1.0/bits/stl_algo.h:1940:31,
inlined from 'void std::__sort(_RandomAccessIterator, _RandomAccessIterator, _Compare) [with _RandomAccessIterator = int*; _Compare = __gnu_cxx::__ops::_Iter_less_iter]' at /opt/compiler-explorer/gcc-12.1.0/include/c++/12.1.0/bits/stl_algo.h:1932:5,
inlined from 'void std::sort(_RAIter, _RAIter) [with _RAIter = int*]' at /opt/compiler-explorer/gcc-12.1.0/include/c++/12.1.0/bits/stl_algo.h:4820:18,
inlined from 'int main()' at <source>:16:15:
/opt/compiler-explorer/gcc-12.1.0/include/c++/12.1.0/bits/stl_algo.h:1849:32: error: array subscript 16 is outside array bounds of 'std::array<int, 8> [1]' [-Werror=array-bounds]
1849 | std::__insertion_sort(__first, __first + int(_S_threshold), __comp);
| ~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
<source>: In function 'int main()':
<source>:7:27: note: at offset 64 into object 'test' of size 32
7 | std::array<int,8> test{};
I believe that to be mistaken. According to my limited understanding, valid is only incremented once and will always be 1.
Even if the condition were replaced with some unpredictable function call, in the worst case it would be true every time, yielding valid==8 at the end of the loop, which should still be alright?
Additionally, I have thus far made the following observations:
The warning is not produced at lower optimization levels, on gcc <=11 or on clang.
Interestingly, the warning is also not produce with array sizes >8 or <6, only for sizes 6,7, and 8.
When I remove the condition inside the loop body(the "if(i==0)", to increment every time and always yield valid==8), the warning disappears.
When I add the condition before the sort call(and thereby provide the compiler with an additional hint about the limits of valid), the warning disappears.
Especially the latter two make me believe I might have managed to confuse gcc's analysis somehow, but also make me question if I am overlooking something obvious or managed to introduce some subtle undefined behaviour in my code.
Am I misunderstanding something in my sleep deprived state or did I encounter a genuine, mostly harmless, compiler bug?
It is indeed a compiler bug, as can be seen in this bugzilla report, which contains almost identical code to the one in my question.
Thanks to Marc Glisse for providing this link to a lot of similar bugs and thereby helping me track down the relevant one.
Related
I have a bit of code (which I didn't write, but am trying to compile) -- iostream_combo.cc--, and doing so gives me the following error:
./moses/moses/comboreduct/combo/iostream_combo.cc: In function ‘std::__cxx11::string opencog::combo::l2ph(const string&, const std::vector<std::__cxx11::basic_string<char> >&)’:
./moses/moses/comboreduct/combo/iostream_combo.cc:543:64: error: call of overloaded ‘distance(std::vector<std::__cxx11::basic_string<char> >::const_iterator, __gnu_cxx::__normal_iterator<const std::__cxx11::basic_string<char>*, std::vector<std::__cxx11::basic_string<char> > >&)’ is ambiguous
arity_t idx = distance(labels.begin(), found_it) + 1;
^ In file included from /usr/include/c++/8/bits/stl_algobase.h:66,
from /usr/include/c++/8/bits/char_traits.h:39,
from /usr/include/c++/8/ios:40,
from /usr/include/c++/8/ostream:38,
from /usr/include/c++/8/iostream:39,
from ./moses/moses/comboreduct/combo/iostream_combo.h:28,
from ./moses/moses/comboreduct/combo/iostream_combo.cc:24:
/usr/include/c++/8/bits/stl_iterator_base_funcs.h:138:5: note: candidate: ‘typename std::iterator_traits<_Iterator>::difference_type std::distance(_InputIterator, _InputIterator) [with _InputIterator = __gnu_cxx::__normal_iterator<const std::__cxx11::basic_string<char>*, std::vector<std::__cxx11::basic_string<char> > >; typename std::iterator_traits<_Iterator>::difference_type = long int]’
distance(_InputIterator __first, _InputIterator __last)
^~~~~~~~ In file included from /usr/local/include/boost/range/distance.hpp:18,
from /usr/local/include/boost/range/functions.hpp:21,
from /usr/local/include/boost/range/iterator_range_core.hpp:38,
from /usr/local/include/boost/lexical_cast.hpp:30,
from ./moses/moses/comboreduct/combo/iostream_combo.h:30,
from ./moses/moses/comboreduct/combo/iostream_combo.cc:24:
/usr/local/include/boost/iterator/distance.hpp:49:9: note: candidate: ‘constexpr typename boost::iterators::iterator_difference<Iterator>::type boost::iterators::distance_adl_barrier::distance(SinglePassIterator, SinglePassIterator) [with SinglePassIterator = __gnu_cxx::__normal_iterator<const std::__cxx11::basic_string<char>*, std::vector<std::__cxx11::basic_string<char> > >; typename boost::iterators::iterator_difference<Iterator>::type = long int]’
distance(SinglePassIterator first, SinglePassIterator last)
^~~~~~~~
I'm using Ubuntu 16.04 x64, Boost 1.68 and gcc 8.2. So, the steps to reproduce the problem would be as follows:
On Ubuntu 16.04
install gcc-8
Use it to build boost 1.68 from source
Git clone the moses repository sand follow the instructions from there: basically 1) git clone and build cogutil; 2) try to make moses:
cd build, cmake .., make.
I understand C++ enough (I think) that I can see that the call to std::distance is overloaded. What I don't see is the way to disambiguate it, although I guess it must include some re-writing of found_it or some explicit castings instead of auto.
The calls are like:
arity_t idx = distance(labels.begin(), found_it) + 1;
This means that distance is found via ADL and hence all associated namespaces are considered. This might prove problematic if e.g. there are two namespaces providing an equally applicable overload for distance:
Live On Coliru
#include <iterator>
#include <vector>
namespace OyVeh {
struct X { };
template <typename It>
size_t distance(It, It) { return 42; } // just to throw in a wrench
}
int main() {
std::vector<OyVeh::X> v{3};
auto f = v.begin();
auto l = v.end();
// now f and l have both `::std` and `::OyVeh` as associated namespaces. The following is ambiguous:
return distance(f, l);
}
There are roughly 2 ways to fix it:
remove the ambigious distance declaration from the associated namespace (this might not be possible if e.g. the ones competing are std::distance and boost::distance)
edit the calls to remove the reliance on ADL (e.g. qualify them like std::distance(...) or parenthesize them (distance)(...))
Showing the workarounds:
Live On Coliru
{
using OyVeh::distance;
return (distance)(f, l); // parentheses suppress ADL
}
return std::distance(f, l); // also works, obviously
return OyVeh::distance(f, l); // but beware the meaning might change
A colleague has provided me with a package of c++ code based on some Celestrak satellite code https://celestrak.org/software/vallado/cpp.zip.
In several places the code, i.e coordfk5.cpp declares vectors of vectors like
std::vector< std::vector<double> > prec, nut(3,3), st, stdot, pm, pmp
The nut(3,3) and similar declarations won't compile on my system yet does for the colleague on his and presumably others who have downloaded the original package.
stl_vector.h: In instantiation of 'void std::vector<_Tp, _Alloc>::_M_initialize_dispatch(_Integer, _Integer, std::__true_type) [with _Integer = int; _Tp = std::vector; _Alloc = std::allocatorstd::vector<double >]':
stl_vector.h:404:55: required from 'std::vector<_Tp, _Alloc>::vector(_InputIterator, _InputIterator, const allocator_type&) [with _InputIterator = int; _Tp = std::vector; _Alloc = std::allocatorstd::vector<double >; std::vector<_Tp, _Alloc>::allocator_type = std::allocatorstd::vector<double >]'
stl_vector.h:1166:59: error: no matching function for call to 'std::vectorstd::vector<double >::_M_fill_initialize(std::vectorstd::vector<double >::size_type, int&)'
_M_fill_initialize(static_cast<size_type>(__n), __value);
I'm on gcc version 4.8.1, the colleague is on 4.6.3. I've tried adding -std=c++98 etc options to no avail.
I can get the code to compile by changing to eg
nut(3,std::vector<double>(3))
but not sure if this is right as the code then seg faults.
So two questions,
Is it possible with some options/switches to compile the code as is?
If not any idea how these vectors should be declared and set-up?
The nut(3,3) attempts to use 3 as initializer for the inner std::vector<int>.
However, std::vector has an explicit constructor which is why it doesn't compile. As you have found, explicit constructors have to have the type explicitly written, with nut(3, std::vector<int>(3)).
Some older compilers came with a vector that didn't mark the constructor as explicit which would explain your colleagues' observations.
I have a simple c++ std::vector and inside it, i am storing threads as shown below. Can you please explain why the line with comment "does not compile" shows error during compilation? And why the line with comment "compiles" work?
#include<thread>
#include<vector>
using namespace std;
void abc() {}
int main()
{
vector<thread> workers;
workers.push_back(thread(abc)); // compiles
thread t(abc);
workers.push_back(t); // does not compile
return 0;
}
UPDATE: i am using g++ 4.4.6 on linux. Below is the error
[jim#cola c++]$ g++ -std=c++0x -pthread -g -Wall t.cpp -o t
In file included from /usr/lib/gcc/x86_64-redhat-linux/4.4.6/../../../../include/c++/4.4.6/x86_64-redhat-linux/bits/c++allocator.h:34,
from /usr/lib/gcc/x86_64-redhat-linux/4.4.6/../../../../include/c++/4.4.6/bits/allocator.h:48,
from /usr/lib/gcc/x86_64-redhat-linux/4.4.6/../../../../include/c++/4.4.6/string:43,
from /usr/lib/gcc/x86_64-redhat-linux/4.4.6/../../../../include/c++/4.4.6/bits/locale_classes.h:42,
from /usr/lib/gcc/x86_64-redhat-linux/4.4.6/../../../../include/c++/4.4.6/bits/ios_base.h:43,
from /usr/lib/gcc/x86_64-redhat-linux/4.4.6/../../../../include/c++/4.4.6/ios:43,
from /usr/lib/gcc/x86_64-redhat-linux/4.4.6/../../../../include/c++/4.4.6/ostream:40,
from /usr/lib/gcc/x86_64-redhat-linux/4.4.6/../../../../include/c++/4.4.6/iostream:40,
from t.cpp:1:
/usr/lib/gcc/x86_64-redhat-linux/4.4.6/../../../../include/c++/4.4.6/thread: In member function ‘void __gnu_cxx::new_allocator<_Tp>::construct(_Tp*, const _Tp&) [with _Tp = std::thread]’:
/usr/lib/gcc/x86_64-redhat-linux/4.4.6/../../../../include/c++/4.4.6/bits/stl_vector.h:737: instantiated from ‘void std::vector<_Tp, _Alloc>::push_back(const _Tp&) [with _Tp = std::thread, _Alloc = std::allocator<std::thread>]’
t.cpp:29: instantiated from here
/usr/lib/gcc/x86_64-redhat-linux/4.4.6/../../../../include/c++/4.4.6/thread:122: error: deleted function ‘std::thread::thread(const std::thread&)’
/usr/lib/gcc/x86_64-redhat-linux/4.4.6/../../../../include/c++/4.4.6/ext/new_allocator.h:105: error: used here
In file included from /usr/lib/gcc/x86_64-redhat-linux/4.4.6/../../../../include/c++/4.4.6/vector:69,
from t.cpp:4:
/usr/lib/gcc/x86_64-redhat-linux/4.4.6/../../../../include/c++/4.4.6/thread: In member function ‘void std::vector<_Tp, _Alloc>::_M_insert_aux(__gnu_cxx::__normal_iterator<typename std::_Vector_base<_Tp, _Alloc>::_Tp_alloc_type::pointer, std::vector<_Tp, _Alloc> >, _Args&& ...) [with _Args = const std::thread&, _Tp = std::thread, _Alloc = std::allocator<std::thread>]’:
/usr/lib/gcc/x86_64-redhat-linux/4.4.6/../../../../include/c++/4.4.6/bits/stl_vector.h:741: instantiated from ‘void std::vector<_Tp, _Alloc>::push_back(const _Tp&) [with _Tp = std::thread, _Alloc = std::allocator<std::thread>]’
t.cpp:29: instantiated from here
/usr/lib/gcc/x86_64-redhat-linux/4.4.6/../../../../include/c++/4.4.6/thread:122: error: deleted function ‘std::thread::thread(const std::thread&)’
/usr/lib/gcc/x86_64-redhat-linux/4.4.6/../../../../include/c++/4.4.6/bits/vector.tcc:314: error: used here
You're getting the error because std::thread is noncopyable, and you're trying to insert a copy of t into the vector.
The only way you could make this work would be to do:
workers.push_back(std::move(t));
However, this would mean that after you do that, t no longer represents a thread (the thread it represented was moved into the vector).
The reason is that std::thread has a move constructor, but doesn't have a copy constructor.
Here is a cleaner and faster solution that requires neither copying nor moving:
workers.emplace_back(abc);
Because std::thread is not copyable, you could move it to vector though:
thread t(abc);
workers.push_back(std::move(t));
Better solution is to store smart pointer in vector:
std::vector<std::shared_ptr<std::thread>> workers;
Because when work with lambda, there is no way to capture a move only type, a workaround is to store a move-only type in std::shared_ptr<std::thread>.
i'm using gcc 4.6.2.
I'm trying to push_back in a vector shared_ptr's.
But gcc gives me everytime an error.
Here my codelines:
std::vector< std::tr1::shared_ptr<Process> > procs;
std::string line;
while (getline(file, line) && line.find(JobMask) != std::string::npos)
{
std::string procName = line.substr(line.find(JobMask) + JobMask.size());
std::vector<Instruction> procInstructions = extractProgram(file);
std::queue<int> procInputs = extractInputs(file);
if (!procInstructions.empty())
procs.push_back(std::make_shared<Process>(Process(procName, procInputs, procInstructions))); //line 51
}
return procs;
The Error my gcc is giving is:
Process.cpp: In static member function 'static std::vector<std::tr1::shared_ptr<RMMIX::Process> > RMMIX::Process::createProcesses(const string&)':
Process.cpp:51:95: error: no matching function for call to 'std::vector<std::tr1::shared_ptr<RMMIX::Process> >::push_back(std::shared_ptr<RMMIX::Process>)'
Process.cpp:51:95: note: candidates are:
/usr/lib/gcc/x86_64-pc-linux-gnu/4.6.2/include/g++-v4/bits/stl_vector.h:826:7: note: void std::vector<_Tp, _Alloc>::push_back(const value_type&) [with _Tp = std::tr1::shared_ptr<RMMIX::Process>, _Alloc = std::allocator<std::tr1::shared_ptr<RMMIX::Process> >, std::vector<_Tp, _Alloc>::value_type = std::tr1::shared_ptr<RMMIX::Process>]
/usr/lib/gcc/x86_64-pc-linux-gnu/4.6.2/include/g++-v4/bits/stl_vector.h:826:7: note: no known conversion for argument 1 from 'std::shared_ptr<RMMIX::Process>' to 'const value_type& {aka const std::tr1::shared_ptr<RMMIX::Process>&}'
/usr/lib/gcc/x86_64-pc-linux-gnu/4.6.2/include/g++-v4/bits/stl_vector.h:839:7: note: void std::vector<_Tp, _Alloc>::push_back(std::vector<_Tp, _Alloc>::value_type&&) [with _Tp = std::tr1::shared_ptr<RMMIX::Process>, _Alloc = std::allocator<std::tr1::shared_ptr<RMMIX::Process> >, std::vector<_Tp, _Alloc>::value_type = std::tr1::shared_ptr<RMMIX::Process>]
/usr/lib/gcc/x86_64-pc-linux-gnu/4.6.2/include/g++-v4/bits/stl_vector.h:839:7: note: no known conversion for argument 1 from 'std::shared_ptr<RMMIX::Process>' to 'std::vector<std::tr1::shared_ptr<RMMIX::Process> >::value_type&& {aka std::tr1::shared_ptr<RMMIX::Process>&&}'
In my eyes the error say's, that std::make_shared create a std::shared_ptr.
But in gcc shared_ptr is in the namespace std::tr1.
How could i fix it?
If I understand correctly, make_shared is new in C++11 and is in namespace std, but it is only available if you compile with -std=gnu++0x or similar. But if you do that, then shared_ptr is also in std.
The problem is that there is another version of shared_ptr in std::tr1, but in C++11 mode you should not use it: it should be considered deprecated.
Your solution is simply to remove every use of tr1 and use the full C++11 version of these classes.
C++ template error message can be a beast to read. But the answer is in the 2nd note.
no known conversion for argument 1 from 'std::shared_ptr<RMMIX::Process>' to 'const value_type& {aka const std::tr1::shared_ptr<RMMIX::Process>&}'
The problem is you're using std::make_shared (which creates a std::shared_ptr) and passing it into a vector of std::tr1::shared_ptr.
The simplest solution is drop the TR1. The stuff from the TR1 was some of first features implemented by compilers when adding C++11 support.
std::vector< std::shared_ptr<Process> > procs;
If you are unable to stop using std::tr1::shared_ptr. You'll have to forgo using make_shared as it was not part of the TR1.
In my project, I recently decided to use boost::thread. My code compiles fine under Linux, but under Windows (either x86 or x64), I get the following warnings with gcc 4.5:
In file included from C:\Boost\include\boost-1_44/boost/thread/shared_mutex.hpp:14:0,
from C:\Boost\include\boost-1_44/boost/thread/detail/thread_group.hpp:9,
from C:\Boost\include\boost-1_44/boost/thread/thread.hpp:24,
from C:\Boost\include\boost-1_44/boost/thread.hpp:13,
from include\systools/upnp_control_point.hpp:50,
from src\upnp_control_point.cpp:45:
C:\Boost\include\boost-1_44/boost/thread/win32/shared_mutex.hpp: In member function 'T boost::shared_mutex::interlocked_
compare_exchange(T*, T, T) [with T = boost::shared_mutex::state_data]':
C:\Boost\include\boost-1_44/boost/thread/win32/shared_mutex.hpp:110:103: instantiated from here
C:\Boost\include\boost-1_44/boost/thread/win32/shared_mutex.hpp:50:99: error: dereferencing type-punned pointer will bre
ak strict-aliasing rules
C:\Boost\include\boost-1_44/boost/thread/win32/shared_mutex.hpp:50:99: error: dereferencing type-punned pointer will bre
ak strict-aliasing rules
C:\Boost\include\boost-1_44/boost/thread/win32/shared_mutex.hpp:51:52: error: dereferencing type-punned pointer will bre
ak strict-aliasing rules
C:\Boost\include\boost-1_44/boost/thread/win32/shared_mutex.hpp:51:52: error: dereferencing type-punned pointer will bre
ak strict-aliasing rules
In file included from C:\Boost\include\boost-1_44/boost/algorithm/string/detail/find_format.hpp:18:0,
from C:\Boost\include\boost-1_44/boost/algorithm/string/find_format.hpp:23,
from C:\Boost\include\boost-1_44/boost/algorithm/string/replace.hpp:22,
from C:\Boost\include\boost-1_44/boost/date_time/date_facet.hpp:17,
from C:\Boost\include\boost-1_44/boost/date_time/gregorian/gregorian_io.hpp:16,
from C:\Boost\include\boost-1_44/boost/date_time/gregorian/gregorian.hpp:31,
from C:\Boost\include\boost-1_44/boost/date_time/posix_time/time_formatters.hpp:12,
from C:\Boost\include\boost-1_44/boost/date_time/posix_time/posix_time.hpp:24,
from include\systools/upnp_device.hpp:51,
from include\systools/upnp_control_point.hpp:48,
from src\upnp_control_point.cpp:45:
C:\Boost\include\boost-1_44/boost/algorithm/string/detail/find_format_store.hpp: At global scope:
C:\Boost\include\boost-1_44/boost/algorithm/string/detail/find_format_store.hpp: In instantiation of 'bool boost::algori
thm::detail::check_find_result(InputT&, FindResultT&) [with InputT = std::basic_string<char>, FindResultT = boost::itera
tor_range<__gnu_cxx::__normal_iterator<char*, std::basic_string<char> > >]':
C:\Boost\include\boost-1_44/boost/algorithm/string/detail/find_format_all.hpp:259:17: instantiated from 'void boost::a
lgorithm::detail::find_format_all_impl(InputT&, FinderT, FormatterT, FindResultT) [with InputT = std::basic_string<char>
, FinderT = boost::algorithm::detail::first_finderF<const char*, boost::algorithm::is_equal>, FormatterT = boost::algori
thm::detail::const_formatF<boost::iterator_range<const char*> >, FindResultT = boost::iterator_range<__gnu_cxx::__normal
_iterator<char*, std::basic_string<char> > >]'
C:\Boost\include\boost-1_44/boost/algorithm/string/find_format.hpp:268:13: instantiated from 'void boost::algorithm::f
ind_format_all(SequenceT&, FinderT, FormatterT) [with SequenceT = std::basic_string<char>, FinderT = boost::algorithm::d
etail::first_finderF<const char*, boost::algorithm::is_equal>, FormatterT = boost::algorithm::detail::const_formatF<boos
t::iterator_range<const char*> >]'
C:\Boost\include\boost-1_44/boost/algorithm/string/replace.hpp:654:13: instantiated from 'void boost::algorithm::repla
ce_all(SequenceT&, const Range1T&, const Range2T&) [with SequenceT = std::basic_string<char>, Range1T = char [15], Range
2T = char [1]]'
C:\Boost\include\boost-1_44/boost/units/detail/utility.hpp:50:51: instantiated from here
C:\Boost\include\boost-1_44/boost/algorithm/string/detail/find_format_store.hpp:74:18: error: unused parameter 'Input'
scons: *** [src\upnp_control_point.o] Error 1
scons: building terminated because of errors.
I just included <boost/thread.hpp> in my own .cpp file, nothing special.
Since I have no control over boost's code, is there a way to suppress those warnings temporarily ? Something like:
#super_killing_macro_that_disable_some_warnings
#include <boost/thread.hpp>
#its_all_good_know_i_want_my_warnings_back
What can I do ?
I just discovered the -isystem option that allow to include a directory as a system directory. No warnings are emited from files within thoses directories so it seems perfect for my task.
Also, this has the neat side effect to make SCons ignore those directories as well in the dependency tree. Since I'm not expecting those libraries to change often, it's fine.
you may have some luck with diagnostic pragma:
http://gcc.gnu.org/onlinedocs/gcc/Diagnostic-Pragmas.html
I am having almost the same warnings on Windows XP SP3 with MinGW installed from mingw-get-inst-20101030 with GCC 4.5.0 and boost 1.45.0 built as indicated here
http://fw-geekycoder.blogspot.com/2010/12/building-boost-using-mingw.html
I am using the BOOST_THREAD_USE_LIB compiler flag and the -lboost_thread-mgw45-mt-1_45 linker flag. The only four warnings I am getting are as follows at the end of this post.
C:\workspace\boost_1_45_0/boost/thread/win32/shared_mutex.hpp:113:103: instantiated from here
C:\workspace\boost_1_45_0/boost/thread/win32/shared_mutex.hpp:53:99: warning: dereferencing type-punned pointer will break strict-aliasing rules
C:\workspace\boost_1_45_0/boost/thread/win32/shared_mutex.hpp:53:99: warning: dereferencing type-punned pointer will break strict-aliasing rules
C:\workspace\boost_1_45_0/boost/thread/win32/shared_mutex.hpp:54:52: warning: dereferencing type-punned pointer will break strict-aliasing rules
C:\workspace\boost_1_45_0/boost/thread/win32/shared_mutex.hpp:54:52: warning: dereferencing type-punned pointer will break strict-aliasing rules
I haven't been able to get the resulting code not to crash yet, so I don't know if these warnings are important or not (by checking to see if threading changes my numerical results).