views:

406

answers:

2

Brief version of my question:

This code crashes the compiler.

pThread[0] = new boost::thread(
boost::bind(
    &cGridAnimator::DoJob,  // member function
       this ),                 // instance of class
       0 );                 // job number

The compiler crashes when attempting to compile this code. ( It is not my program that crashe when I run this code! )

What needs to be fixed?


Long version of question

I am splitting up the work on a large 3D grid into 8 seperate jobs to be run in seperate threads, so as to take advantage of an 8 core machine.

This works perfectly:

 JOB_LOOP {
  pThread[kjob] = new boost::thread( ::DoJob, kjob );
 }

The global free function DoJob reads the data from a global instance of cGridAnimator, according to the job number.

However, I do not like all these globals floating around, and I do not like having to use so many accessor methods to get at the necessary data. It would be much tidier to use a method of cGridAnimator.

Hence the code at the top of this question.

However, when I compile it on MSVC++ 2008 the compiler issues the following complaints and then crashes.

1>Compiling...
1>mfm1.cpp
1>C:\Program Files\boost\boost_1_38_0\boost/bind.hpp(1643) : warning C4180: qualifier applied to function type has no meaning; ignored
1>        C:\Program Files\boost\boost_1_38_0\boost/bind.hpp(1677) : see reference to class template instantiation 'boost::_bi::add_cref<Pm,I>' being compiled
1>        with
1>        [
1>            Pm=void (__thiscall cGridAnimator::* )(int),
1>            I=1
1>        ]
1>        .\mfm1.cpp(158) : see reference to class template instantiation 'boost::_bi::dm_result<Pm,A1>' being compiled
1>        with
1>        [
1>            Pm=void (__thiscall cGridAnimator::* )(int),
1>            A1=cGridAnimator *
1>        ]
1>C:\Program Files\boost\boost_1_38_0\boost/mem_fn.hpp(318) : warning C4180: qualifier applied to function type has no meaning; ignored
1>        C:\Program Files\boost\boost_1_38_0\boost/bind/bind_template.hpp(344) : see reference to class template instantiation 'boost::_mfi::dm<R,T>' being compiled
1>        with
1>        [
1>            R=void (int),
1>            T=cGridAnimator
1>        ]
1>Project : error PRJ0002 : Error result 1 returned from 'C:\Program Files\Microsoft Visual Studio 9.0\VC\bin\cl.exe'.
+2  A: 

There is no definitive answer; basically, an ICE is always a good reason to contact the compiler vendor.

To find the real cause it will help to try to find the minimal program which still exhibits the crash. This means removing as much code as possible, removing as many dependencies as possible, etc. etc. For one ICE I've once had success with starting a new project, and just writing the fifty-some lines of code where I suspected the issue.

Following workarounds helped me in the past:

  1. reduce optimization level
    • especially link time code generation seems to be a bit shaky
  2. change order of include files
    • only sensible if you know the revision of the source when it stopped working, so you can concentrate on the changes there
  3. switch to a different boost version
    • the boost library author may have activated a workaround, or the code just changed enough to not cause an ICE anymore.
gimpf
+3  A: 

Change the code into:

pThread[0] = new boost::thread(boost::bind(&cGridAnimator::DoJob, this, 0 ));

This code gives a void (void) function to the thread instead of a void (int) function and an extra argument.

Willy
This fixes the compiler crash. I will do some tests, and if it works accept this answer.
ravenspoint
Nice catch! As the answer is stated as this would be so obvious: How did you find that out?
gimpf
You can see the Signature of DoJob in the warning message. I have the same compiler crashes almost each time the numbers of arguments don't fit.
Willy