tags:

views:

159

answers:

2

Hey Guys

I have a simple wrapper for an Mersenne twister random number generator. The purpose is to scale the number returned by the generator (between 0 and 1) to between argument defined limits (begin and end).

So my function is

inline float xlRandomFloat(float begin, float end) {return (begin+((end-begin)*genrand_real2()));}

I don't believe the implementation of genrand_real2() function is important, but if I am wrong it can be found here

The problem is the function does not return the translated result. The scaling (multiplying by (begin-end) seems to work correctly, but the addition of begin does not seem to be returned.

So if I call xlRandomFloat(5,10) - I get values between 0 and 5.

If I debug with GDB, and use the print function then it shows the correct result. So then I tried separating things into lines to see what happens

inline float xlRandomFloat(float begin, float end) {
    float ret;
    ret=(((end-begin)*genrand_real2()));
    ret+=begin;
    return ret;};

When debugging, it jumped straight from the first line into the genrand_real2() function and skipped out every thing else entirely. That was really confusing so I thought it may have something to do with the inlining. I moved the file from this .hpp file to the .cpp and removed the inline keyword and everything works correctly.

But why does this behavior occur, and how can I inline this function? Also, I am not sure if this is relevant, but often when I made changes to the sources, my Make compilation would say there is nothing to be done. Which is unusual since normally I expect make to pick up on changes in the sources and rebuild accordingly.

Any ideas.

Thanks

Zenna

+1  A: 

Your code is perfectly fine, there must be something wrong with the way you're compiling. Make sure your Makefile has the proper dependencies: the source files need to depend on the header files that they include. Tracking these dependencies is rarely done by hand, usually only for very small projects -- they are normally generated by a tool such as makedepend.

To see if inlining is causing the problem, just disable all optimizations by using the -O0 (dash capital-oh zero) option with GCC. Also make sure to enable debugging symbols with -g.

Adam Rosenfield
Thanks a lotYou are right. I built it with codeblocks and it works correctly. At the moment, I have the following structure:all: $(SOURCES) $(EXECUTABLE)$(EXECUTABLE): $(OBJECTS) $(CC) $(LDFLAGS) $(OBJECTS) -o [email protected]: $(CC) $(CFLAGS) $< -o $@As you said I'll try to include the header dependency, but I thought the dependencies were to nudge Make to recompile due to a headers being modified, if I rebuild everything from scratch however,how could that make a difference?
zenna
+1  A: 

Okay, several things at work here.

First, on the debugging, you describe what I'd think of as the more or less expected behavior, because when you inline a function, there's no generated code to go with the fromt matter of the function. So, the first statement there is

ret=(((end-begin)*genrand_real2()));

and the first step on that is to call genrand_real2(). If genrand_real2() is also inline, then you end up at the first statement in that, with no pause to catch your breath.

Second, make sure you're really running the code you think you are. Try making from a clean directory --some C++ compilers make precompiled pieces that they preserve to speed compilation. Make sure your inline definition has been completely removes or commented out from the header files. m

Thrd, make a very simple program with an inline and make sure it's behaving as you expect.

Charlie Martin