2

Say I have the following lines of code:

int a = rand();
int b = rand();
int c = rand(); 

Is there any way, when debugging, to make it so that 'rand()' will return, say, 1, then 2, then 3 to variables a, b, and c, respectively?

If not (which I assume is likely the case), is there an easy Ctrl-F replacement method where I can hardcode in these values when debugging?

klutt
  • 30,332
  • 17
  • 55
  • 95
littleNybble
  • 23
  • 1
  • 3
  • 1
    For `rand` specifically you could seed it with a fixed number, so it'll always return the same values each run. – Random Davis Feb 02 '21 at 21:03
  • Normally the debugger should let you set the values of variables, so just setting a breakpoint after the function returns should let you modify the value of the variable. – icebp Feb 02 '21 at 21:12
  • You can use `srand` to set the seed. What I do for this is have a command line arg such as: `-R123456`. I decode that value as `seed` and pass it to `srand`. Or, if no `-R` given, the seed value is (e.g) `seed = time(NULL);`. In either case, I print out the seed value so I can cut-and-paste it to `-R` on a second run. If necessary, you can have _multiple_ seed values and use `rand_r` – Craig Estey Feb 02 '21 at 21:17

2 Answers2

6

One option is to use a preprocessor macro to 'override' the rand function, and compile with -DDEBUG.

#ifdef DEBUG
#define rand() debug_rand()
static int debug_rand() {
    static int n = 1;

    return n++;
}
#endif

Depending on the complexity of your project you may want to control the scope of this with additional #ifdef and #undef conditionals.


Alternatively, you could conditionally adjust your srand call.

#ifdef DEBUG
    srand(1);
#else
    srand(/* your usual seed gen */); 
#endif

What this does is cause your program to behave predictably.

You could write a separate program to map out the default set of values returned by N rand() calls on your system, and use that as a reference sheet.

Oka
  • 23,367
  • 6
  • 42
  • 53
  • The macro is unnecessary. The linker will resolve symbols in provided object modules before it searches the library, so merely defining rand() will override the library implementation. – Clifford Feb 02 '21 at 22:07
  • @Clifford and that's not quite true, after all, `rand` is a builtin function and its redefinition by any means leads to undefined behaviour... – Antti Haapala -- Слава Україні Feb 02 '21 at 22:13
  • @Clifford Depends on the scope you desire, as well. Here we can `#undef` the macro and `debug_rand` remains hidden away in the unit. To 'overload' the standard library function we'd need to drop our `static` storage class, and UB follows. – Oka Feb 02 '21 at 22:15
  • @Oka That is a fair point - if you wanted rand to behave normally elsewhere you have that flexibility with a macro. – Clifford Feb 02 '21 at 22:29
  • @AnttiHaapala : Library functions are in libraries, rand() is not a build-in in any compiler I am aware of. Nor is it undefined behaviour or an an overload - only one version exists in the link and the behaviour of the linker in this case is clear(https://stackoverflow.com/questions/19023018/overriding-c-library-functions-calling-original). You are simply resolving the link "early" in order to block linking the library implementation. https://onlinegdb.com/SJ3gZ8veu – Clifford Feb 02 '21 at 22:33
  • @AnttiHaapala It is however academic - the fact that Oka declared it `static` means that the macro is in fact necessary to his answer. He makes a good case for doing that, but it does prevent the compiler from ensuring that the function signature exactly matches that the standard header declaration. – Clifford Feb 02 '21 at 22:45
1

What you want to do is called mocking

Is there any way, when debugging, to make it so that 'rand()' will return, say, 1, then 2, then 3 to variables a, b, and c, respectively?

Depends. Usually, you call srand(<seed>); once in your program. If you're ok with calling it each time before a rand() call you can find a seed that gives the desired output and call srand with that seed.

If the question is "Can I find a seed that gives this particular sequence in the beginning?" the answer is that it may be easy or hard depending on the length of the sequence.

Another option for debugging is to simply define your own random function while you're debugging. Like in Oka's answer

klutt
  • 30,332
  • 17
  • 55
  • 95