This is the code in question:
void DeckTug::StickCallback(unsigned long long evtID, DWORD value)
{
long int val = value;
if (evtID == stickXInputID || evtID == stickAxisXInputID)
stickXpct = (((double)val)) / 325.94;
else if (evtID == stickYInputID || evtID == stickAxisYInputID) {
stickYpct = (((double)val)) / 325.94;
if(isAuto)
if ((stickYpct < 0.0)) {
acPullingTug = true;
tugTBoffset = tugReversed ? towbarAttachAft * (-1.0) : towbarAttachForward;
}
else {
acPullingTug = false;
tugTBoffset = tugReversed ? towbarAttachAft * (-1.0) : towbarAttachForward;
}
}
}
When I compile a debug build, this runs perfectly. When I compile a release build, it does not work. When I attach the visual studio debugger to the release version, I can break on the first if statement and on the closing brace of the function, but I cannot hit a break point anywhere else, and neither stickXpct or stickYpct are ever being assigned anything, although in the debugger I can see that "value" has a valid value, and "evtID" DOES equal one of inputIDs.
In conclusion, it looks to me like, in the release version of the code only, both the first "if" statement and the first "else if" statement only evaluate to false, even when one of them should evaluate to true. Does anyone know what is going on here? because I don't.
Thanks so much,
Farley
Edit: changed answer in response to comments
Try adding volatility
void DeckTug::StickCallback(unsigned long long evtID, DWORD value)
{
long int val = value;
volatile unsigned long long _evtID = evtID;
if (_evtID == stickXInputID || _evtID == stickAxisXInputID)
stickXpct = (((double)val)) / 325.94;
else if (_evtID == stickYInputID || _evtID == stickAxisYInputID) {
stickYpct = (((double)val)) / 325.94;
if(isAuto)
if ((stickYpct < 0.0)) {
acPullingTug = true;
tugTBoffset = tugReversed ? towbarAttachAft * (-1.0) : towbarAttachForward;
}
else {
acPullingTug = false;
tugTBoffset = tugReversed ? towbarAttachAft * (-1.0) : towbarAttachForward;
}
}
}
That should prevent the compiler from optimizing those branches until you can track down why it wants to optimize those branches away.
This is some old code not written by me. It compiles with GCC 3.4.6, but now we are checking the build with GCC 4.4.7 and the build fails.
I hope this code is enough to go on:
list<Chapter*> * tocP; //Chapter is a class
tocP = NULL;
if (_searchChapter)
{
_chapter = _manager->GetCurrentChapter(); // _chapter is a Chapter*
}
else
{
tocP = _manager->GetTableOfContents();
if (tocP != NULL && tocP->size() > 0)
_chapter = tocP->front();
}
...
list<Chapter*>::iterator chp;
if (tocP != NULL && tocP->size() > 0)
for (chp=find(tocP->begin(),tocP->end(),_chapter); chp != tocP->end(); ++chp) // this code fails
{
//code to process chapter
}
error message is:
../src/HelpSearchC.C: In member function 'int HelpSearchC_i::DoSearch()':
../src/HelpSearchC.C:685: error: no matching function for call to 'find(std::_List_iterator<Chapter*>,
std::_List_iterator<Chapter*>, Chapter*&)'
You have to add #include <algorithm> on top of the file. The function find is defined within this header.
I recently come across the below piece of code in this Apache Axis tutorial example.
int main()
{
int status = AXIS2_SUCCESS;
axutil_env_t *env = NULL;
axutil_allocator_t *allocator = NULL;
env = create_environment();
status = build_and_serialize_om(env);
(status == AXIS2_FAILURE)
{
printf(" build AXIOM failed");
}
axutil_env_free(env);
0;
}
What i don't understand is the 0; at the end.
Is that return statement without the return keyword?
I tried the below piece of code to test this in Visual Studio.
int main()
{
0; // in the second run, replaced 0 with 28
}
Both programmes ran without any problems. But echo %ERRORLEVEL% at
windows command line returned 0 for both.
But the below piece of code
int add()
{
0;
}
causes
Error 1 error C4716: 'add' : must return a value
I understand that return value 0 is implicitly added for the main().
I don't have a problem including the return keyword at all, but I am
porting the Axis2/C Library to a C++ project. And there are many instances
where I encountered 0;
Why is the above syntax causing this undefined behavior?
In C++ return can be omitted only in main() , in functions that return void, and in constructors and destructors. In the former case main() returns automatically 0. In your case the statement 0; is a syntactically correct statement, evaluated as a no-op, so the compiler is basically ignoring it.
Where did you find that code? It seems like it's corrupted, perhaps due to formatting for showing it on a web page or something...?
The original code (from https://github.com/bnoordhuis/axis2-c/blob/master/axiom/test/util/axiom_util_test.c) is:
int main()
{
int status = AXIS2_SUCCESS;
axutil_env_t *env = NULL;
status = build_and_serialize_om(env);
if(status == AXIS2_FAILURE)
{
printf(" build AXIOM failed");
}
axutil_env_free(env);
return 0;
}
When testing my code (static analysis) to see if i respect misra c++ 2008, i get the following error
Function does not return a value on all paths.
The function looks like
int* Dosomething(string v)
{
int* retvalue = NULL;
if( 0 == exists(v) )
{
throw("error: value doesn't exist");
}
else
{
retvalue = dosomecomputations(v);
}
return retvalue;
}
I really need to throw an exception, because depending of the error the caller shall do something. The possible list of errors can be big and it is not just that the value doesn't exist as in this sample of code.
How can i manage it? I think that in this case the tool i'm using should not see it as a non-compliance to misra.
Thanks for your advise.
rony.
The following code should not report any warnings/errors with MISRA C++ 2008 rules applied. So most likely it's an issue with your tool - or the posted code is not the affected part.
#include <string>
int exists(std::string v){ (void)v; return 1; }
int* dosomecomputations(std::string v){ (void)v; return NULL; }
int* dosomething(std::string v){
int* retvalue = NULL;
if( 0 == exists(v) ){
throw("error: value doesn't exist");
}else{
retvalue = dosomecomputations(v);
}
return retvalue;
}
Try to check just the snippet above with your MISRA checker and see if it's still reporting anything. If the problem persists I would just contact the toolvendor and ask him about that issue.
I am running a program on 2 different machines. On one it works fine without issue. On the other it results in a segmentation fault. Through debugging, I have figured out where the fault occurs, but I can't figure out a logical reason for it to happen.
In one function I have the following code:
pass_particles(particle_grid, particle_properties, input_data, coll_eros_track, collision_number_part, world, grid_rank_lookup, grid_locations);
cout<<"done passing particles"<<endl;
The function pass_particles looks like:
void pass_particles(map<int,map<int,Particle> > & particle_grid, std::vector<Particle_props> & particle_properties, User_input& input_data, data_tracking & coll_eros_track, vector<int> & collision_number_part, mpi::communicator & world, std::map<int,int> & grid_rank_lookup, map<int,std::vector<double> > & grid_locations)
{
//cout<<"east-west"<<endl;
//east-west exchange (x direction)
map<int, vector<Particle> > particles_to_be_sent_east;
map<int, vector<Particle> > particles_to_be_sent_west;
vector<Particle> particles_received_east;
vector<Particle> particles_received_west;
int counter_x_sent=0;
int counter_x_received=0;
for(grid_iter=particle_grid.begin();grid_iter!=particle_grid.end();grid_iter++)
{
map<int,Particle>::iterator part_iter;
for (part_iter=grid_iter->second.begin();part_iter!=grid_iter->second.end();)
{
if (particle_properties[part_iter->second.global_part_num()].particle_in_box()[grid_iter->first])
{
//decide if a particle has left the box...need to consider whether particle was already outside the box
if ((part_iter->second.position().x()<(grid_locations[grid_iter->first][0]) && part_iter->second.position().x()>(grid_locations[grid_iter->first-input_data.z_numboxes()][0]))
|| (input_data.periodic_walls_x() && (grid_iter->first-floor(grid_iter->first/(input_data.xz_numboxes()))*input_data.xz_numboxes()<input_data.z_numboxes()) && (part_iter->second.position().x()>(grid_locations[input_data.total_boxes()-1][0]))))
{
particles_to_be_sent_west[grid_iter->first].push_back(part_iter->second);
particle_properties[particle_grid[grid_iter->first][part_iter->first].global_part_num()].particle_in_box()[grid_iter->first]=false;
counter_sent++;
counter_x_sent++;
}
else if ((part_iter->second.position().x()>(grid_locations[grid_iter->first][1]) && part_iter->second.position().x()<(grid_locations[grid_iter->first+input_data.z_numboxes()][1]))
|| (input_data.periodic_walls_x() && (grid_iter->first-floor(grid_iter->first/(input_data.xz_numboxes()))*input_data.xz_numboxes())>input_data.xz_numboxes()-input_data.z_numboxes()-1) && (part_iter->second.position().x()<(grid_locations[0][1])))
{
particles_to_be_sent_east[grid_iter->first].push_back(part_iter->second);
particle_properties[particle_grid[grid_iter->first][part_iter->first].global_part_num()].particle_in_box()[grid_iter->first]=false;
counter_sent++;
counter_x_sent++;
}
//select particles in overlap areas to send to neighboring cells
else if ((part_iter->second.position().x()>(grid_locations[grid_iter->first][0]) && part_iter->second.position().x()<(grid_locations[grid_iter->first][0]+input_data.diam_large())))
{
particles_to_be_sent_west[grid_iter->first].push_back(part_iter->second);
counter_sent++;
counter_x_sent++;
}
else if ((part_iter->second.position().x()<(grid_locations[grid_iter->first][1]) && part_iter->second.position().x()>(grid_locations[grid_iter->first][1]-input_data.diam_large())))
{
particles_to_be_sent_east[grid_iter->first].push_back(part_iter->second);
counter_sent++;
counter_x_sent++;
}
++part_iter;
}
else if (particles_received_current[grid_iter->first].find(part_iter->first)!=particles_received_current[grid_iter->first].end())
{
if ((part_iter->second.position().x()>(grid_locations[grid_iter->first][0]) && part_iter->second.position().x()<(grid_locations[grid_iter->first][0]+input_data.diam_large())))
{
particles_to_be_sent_west[grid_iter->first].push_back(part_iter->second);
counter_sent++;
counter_x_sent++;
}
else if ((part_iter->second.position().x()<(grid_locations[grid_iter->first][1]) && part_iter->second.position().x()>(grid_locations[grid_iter->first][1]-input_data.diam_large())))
{
particles_to_be_sent_east[grid_iter->first].push_back(part_iter->second);
counter_sent++;
counter_x_sent++;
}
part_iter++;
}
else
{
particle_grid[grid_iter->first].erase(part_iter++);
counter_removed++;
}
}
}
world.barrier();
mpi::request reqs_x_send[particles_to_be_sent_west.size()+particles_to_be_sent_east.size()];
vector<multimap<int,int> > box_sent_x_info;
box_sent_x_info.resize(world.size());
vector<multimap<int,int> > box_received_x_info;
box_received_x_info.resize(world.size());
int counter_x_reqs=0;
//send particles
for(grid_iter_vec=particles_to_be_sent_west.begin();grid_iter_vec!=particles_to_be_sent_west.end();grid_iter_vec++)
{
if (grid_iter_vec->second.size()!=0)
{
//send a particle. 50 will be "west" tag
if (input_data.periodic_walls_x() && (grid_iter_vec->first-floor(grid_iter_vec->first/(input_data.xz_numboxes()))*input_data.xz_numboxes()<input_data.z_numboxes()))
{
reqs_x_send[counter_x_reqs++]=world.isend(grid_rank_lookup[grid_iter_vec->first + input_data.z_numboxes()*(input_data.x_numboxes()-1)], grid_iter_vec->first + input_data.z_numboxes()*(input_data.x_numboxes()-1), particles_to_be_sent_west[grid_iter_vec->first]);
box_sent_x_info[grid_rank_lookup[grid_iter_vec->first + input_data.z_numboxes()*(input_data.x_numboxes()-1)]].insert(pair<int,int>(world.rank(), grid_iter_vec->first + input_data.z_numboxes()*(input_data.x_numboxes()-1)));
}
else if (!(grid_iter_vec->first-floor(grid_iter_vec->first/(input_data.xz_numboxes()))*input_data.xz_numboxes()<input_data.z_numboxes()))
{
reqs_x_send[counter_x_reqs++]=world.isend(grid_rank_lookup[grid_iter_vec->first - input_data.z_numboxes()], grid_iter_vec->first - input_data.z_numboxes(), particles_to_be_sent_west[grid_iter_vec->first]);
box_sent_x_info[grid_rank_lookup[grid_iter_vec->first - input_data.z_numboxes()]].insert(pair<int,int>(world.rank(),grid_iter_vec->first - input_data.z_numboxes()));
}
}
}
for(grid_iter_vec=particles_to_be_sent_east.begin();grid_iter_vec!=particles_to_be_sent_east.end();grid_iter_vec++)
{
if (grid_iter_vec->second.size()!=0)
{
//send a particle. 60 will be "east" tag
if (input_data.periodic_walls_x() && (grid_iter_vec->first-floor(grid_iter_vec->first/(input_data.xz_numboxes())*input_data.xz_numboxes())>input_data.xz_numboxes()-input_data.z_numboxes()-1))
{
reqs_x_send[counter_x_reqs++]=world.isend(grid_rank_lookup[grid_iter_vec->first - input_data.z_numboxes()*(input_data.x_numboxes()-1)], 2000000000-(grid_iter_vec->first - input_data.z_numboxes()*(input_data.x_numboxes()-1)), particles_to_be_sent_east[grid_iter_vec->first]);
box_sent_x_info[grid_rank_lookup[grid_iter_vec->first - input_data.z_numboxes()*(input_data.x_numboxes()-1)]].insert(pair<int,int>(world.rank(),2000000000-(grid_iter_vec->first - input_data.z_numboxes()*(input_data.x_numboxes()-1))));
}
else if (!(grid_iter_vec->first-floor(grid_iter_vec->first/(input_data.xz_numboxes())*input_data.xz_numboxes())>input_data.xz_numboxes()-input_data.z_numboxes()-1))
{
reqs_x_send[counter_x_reqs++]=world.isend(grid_rank_lookup[grid_iter_vec->first + input_data.z_numboxes()], 2000000000-(grid_iter_vec->first + input_data.z_numboxes()), particles_to_be_sent_east[grid_iter_vec->first]);
box_sent_x_info[grid_rank_lookup[grid_iter_vec->first + input_data.z_numboxes()]].insert(pair<int,int>(world.rank(), 2000000000-(grid_iter_vec->first + input_data.z_numboxes())));
}
}
}
counter=0;
for (int i=0;i<world.size();i++)
{
//if (world.rank()!=i)
//{
reqs[counter++]=world.isend(i,1000000000,box_sent_x_info[i]);
reqs[counter++]=world.irecv(i,1000000000,box_received_x_info[i]);
//}
}
mpi::wait_all(reqs, reqs + world.size()*2);
//receive particles
//receive west particles
for (int j=0;j<world.size();j++)
{
multimap<int,int>::iterator received_info_iter;
for (received_info_iter=box_received_x_info[j].begin();received_info_iter!=box_received_x_info[j].end();received_info_iter++)
{
//receive the message
if (received_info_iter->second<1000000000)
{
//receive the message
world.recv(received_info_iter->first,received_info_iter->second,particles_received_west);
//loop through all the received particles and add them to the particle_grid for this processor
for (unsigned int i=0;i<particles_received_west.size();i++)
{
particle_grid[received_info_iter->second].insert(pair<int,Particle>(particles_received_west[i].global_part_num(),particles_received_west[i]));
if(particles_received_west[i].position().x()>grid_locations[received_info_iter->second][0] && particles_received_west[i].position().x()<grid_locations[received_info_iter->second][1])
{
particle_properties[particles_received_west[i].global_part_num()].particle_in_box()[received_info_iter->second]=true;
}
counter_received++;
counter_x_received++;
}
}
else
{
//receive the message
world.recv(received_info_iter->first,received_info_iter->second,particles_received_east);
//loop through all the received particles and add them to the particle_grid for this processor
for (unsigned int i=0;i<particles_received_east.size();i++)
{
particle_grid[2000000000-received_info_iter->second].insert(pair<int,Particle>(particles_received_east[i].global_part_num(),particles_received_east[i]));
if(particles_received_east[i].position().x()>grid_locations[2000000000-received_info_iter->second][0] && particles_received_east[i].position().x()<grid_locations[2000000000-received_info_iter->second][1])
{
particle_properties[particles_received_east[i].global_part_num()].particle_in_box()[2000000000-received_info_iter->second]=true;
}
counter_received++;
counter_x_received++;
}
}
}
}
mpi::wait_all(reqs_y_send, reqs_y_send + particles_to_be_sent_bottom.size()+particles_to_be_sent_top.size());
mpi::wait_all(reqs_z_send, reqs_z_send + particles_to_be_sent_south.size()+particles_to_be_sent_north.size());
mpi::wait_all(reqs_x_send, reqs_x_send + particles_to_be_sent_west.size()+particles_to_be_sent_east.size());
cout<<"x sent "<<counter_x_sent<<" and received "<<counter_x_received<<" from rank "<<world.rank()<<endl;
cout<<"rank "<<world.rank()<<" sent "<<counter_sent<<" and received "<<counter_received<<" and removed "<<counter_removed<<endl;
cout<<"done passing"<<endl;
}
I only posted some of the code (so ignore the fact that some variables may appear to be undefined, as they are in a portion of the code I didn't post)
When I run the code (on the machine in which it fails), I get done passing but not done passing particles
I am lost as to what could possibly cause a segmentation fault between the end of the called function and the next line in the calling function and why it would happen on one machine and not another.
If you're crashing between the end of a function and the subsequent line in the caller, you're probably crashing in the destructor of a local variable. You need to run the program in a debugger to find out which object's destructor is crashing.
There are a couple of possibilities:
You actually are returning, but cout is buffered by the OS so you don't see "done passing particles" because the application crashes first.
You have some local class that has a destructor that is seg faulting.
Try running it in a debugger to find out where it is actually crashing.
Edit:
Since you've mentioned you're using gcc, add the -g flag and run it with gdb. Gdb will then tell you exactly where it's going wrong (probably a null dereference).
Just in case anyone comes back to this later. I updated to the newest version of boost mpi(at the time), 1.50 and this issue went away. Not much of a solution, but it worked.