1

I need to write a physical simulation software, and I need to use the pseudo-random generator written by D.Knuth, cause it best fits my needs.

Though I know how to use it within a hard block of code (a mere #include "rng-double.c"), I can't quite understand how to include it in a modular program where it is needed both within the main and inside some libraries that I then link back into the main through header files.

The only functions that I need are ranf_start(seed) to seed the generator and ranf_arr_next() to generate the next number.

I'm getting a long series of

multiple definitions of 'foo'

pretty much for every function that is defined in the random number generator code.

I'm not an expert, so I find myself pretty much at a dead end. Is there a way out? I am currently trying to write an header file for the rng, though I haven't been successful yet.

Thanks a lot, everybody. ~J

EDIT: From what the first answers say, I need to wirte the header file. I did it for most functions in the generator, but I cant manage to write it right for the function that actually generates the number. How should I write the header for a function defined like this?

#define ranf_arr_next() (*ranf_arr_ptr>=0? *ranf_arr_ptr++: ranf_arr_cycle())
japs
  • 1,286
  • 13
  • 27

3 Answers3

5

You don't include the .c file, but the appropriate header file, which contains the declarations of your functions. The .c file will just be compiled along with the rest.

Eiko
  • 25,601
  • 15
  • 56
  • 71
2

If you ever find yourself #including a .c file, then chances are that you are doing something wrong. You really should be #including .h files only.

This wikipedia link explains exactly the problem you are having and how to write the header file properly.

I suspect your problem is that you are not using the header 'guard' properly.

kikito
  • 51,734
  • 32
  • 149
  • 189
1

rng-double.h

#ifndef RNG_DOUBLE_H_INCLUDED
#define RNG_DOUBLE_H_INCLUDED

extern void ranf_start(long seed);
extern double ranf_next(void);

#ifdef USE_MACRO_RANF_NEXT
extern double *ranf_arr_ptr;
extern double  ranf_arr_cycle(void);
#define ranf_arr_next() (*ranf_arr_ptr >= 0 ? *ranf_ptr++ : ranf_arr_cycle())
#endif /* USE_MACRO_RANF_NEXT */

#endif /* RNG_DOUBLE_H_INCLUDED */

main.c

#include "rng-double.h"
...other stuff...

rng-double.c

#define USE_MACRO_RANF_NEXT
#include "rng-double.h"

double *ranf_arr_ptr;

void ranf_start(long seed)
{
    ...implementation...
}

double (ranf_next)(void)  // Function
{
    ranf_next();          // Macro
}

double ranf_arr_cycle(void)
{
    ...implementation...
}
Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
  • I got rid of the ranf_next function, since I didn't want to modify the original source, if possible. In practice, I moved the whole macro into the header. Thanks for the precious hints though. By the way, in the code you proposed there is a type errors (ranf_start eats long's). – japs Oct 17 '10 at 19:16