Why does clean and recompile remove crashes?

Started by
8 comments, last by Paradigm Shifter 11 years, 4 months ago
Hi
I use visual studio c++ and am a bit confused.

I lately had a crash in my game every time when in a certain situation trying to delete a gameObject from a list containing such elements. It worked before and i didnt change anything special since last working build.

So i did what i usually do when short of ideas, clean project. Recompile. Boom. Problem solved. But why?

Thanks for clearing this up
Erik

this is a ship:
Advertisement
It might be a "misscompile" or "misslink" but, in my experience, those are pretty rare. 99% of the time, in C++, you have an uninitialized variable somewhere or some out of bound access, the new compile might just have hidden that.
Pass the code through CPPCheck and it should catch most of these problems.

Stefano Casillo
TWITTER: [twitter]KunosStefano[/twitter]
AssettoCorsa - netKar PRO - Kunos Simulazioni

This can happen when a header file(let's call it "hello.h")'s class/struct definition is changed, but its corresponding object file ("hello.o") is for some reason not recompiled.

Other object files ("person.o") will link with the old, not recompiled object file ("hello.o").

This "hello.o" will contain old and possibly incorrect code to manipulate the old data structure defined by the old "hello.h", and those code can be used by all sources that #include "hello.h".

Example:
Let's say the old hello.h is like this:

struct hello{
long person_age;
};
void set_age(struct hello * h, long a);


hello.c:

void set_age(struct hello * h, long a)
{
h->age = a;
}



But then you decide a long is not necessary to represent a person's age, and change it to:


struct hello{
char person_age;
};


and then you purposefully not recompile hello.o, but recompile everything else that uses hello.h. Then you link them and hello.o together.

Because the struct definition is updated, but the set_age function isn't, when you call set_age, it will write a long (4 or 8 bytes) into a char (1 byte). That can't be correct, and the program can crash.

By cleaning every thing (every object file), you are forced to recompile every object file. Then functions and the data definitions are up to date with each other, so it "magically" fixes the error.
ok thanks guys
@ultramailman:
This issue happens and I don't understand why.
Object files should be recompiled whenever any of the dependencies is changed. So, why the are not?

@ultramailman:
This issue happens and I don't understand why.
Object files should be recompiled whenever any of the dependencies is changed. So, why the are not?


In my experience, usually because of buggy build tools... or tools that try to be too smart and cache what they shouldn't (I'm looking at you eclipse)

One way it can go wrong is if file dates are messed up, so the tools don't notice that the source file has changed.
Can easily happen if you replace files with old versions of themselfs. (reverting some change for example)

@ultramailman:
This issue happens and I don't understand why.
Object files should be recompiled whenever any of the dependencies is changed. So, why the are not?


I have no idea how that can happen with IDE's. It happens to me because I use make, and write my own makefile. I am not very good with makefiles, so I just use %.o: %.c %.h. So if a person.o depends on hello.h, my makefile wouldn't know about it.
Most compilers have an option to output the dependencies of a .o as they create it. If you capture that in a file and do some simple manipulations on it, you can then include that into your makefile and you have the dependencies done for you.

If you don't want to do that, you can simply put lists of things in your makefile;
[source]
person.o: hello.h anotherfile.h thisandthat.h
[/source]

Pass the code through CPPCheck and it should catch most of these problems.


Thanks for the reference to CPPCheck! That is most useful.wink.png

http://cppcheck.sourceforge.net/
IDEs scan the include files for a compilation unit recursively and work out the dependencies automatically.

If you use a makefile you have to manually add any dependencies, painful, and prone to error. The rule of thumb there is if you change a header, recompile everything... But seriously, use an IDE that does it for you...

Last time I used makefiles was in PS1 days.
"Most people think, great God will come from the sky, take away everything, and make everybody feel high" - Bob Marley

This topic is closed to new replies.

Advertisement