3

Is it good idea to pass uninitialized variable to srand instead of result of time(NULL)?
It is one #include and one function call less.

Example code:

#include <stdlib.h>

int main(void) {
    {
        usigned seed; //uninitialized
        srand(seed);
    }
    //other code
    return 0;
}

instead of

#include <stdlib.h>
#include <time.h>

int main(void) {
    srand(time(NULL));
    //other code
    return 0;
}
GingerPlusPlus
  • 5,336
  • 1
  • 29
  • 52
  • 11
    Why would you think that *any* use of an uninitialized variable is a good idea? – Roger Rowland Nov 12 '14 at 08:08
  • 5
    Initialised doesn't mean random. Just use time(NULL). – Oliver Charlesworth Nov 12 '14 at 08:10
  • Unless you want to generate the same series of random numbers every time you run your program, I don't think it's a good idea. – πάντα ῥεῖ Nov 12 '14 at 08:11
  • Uninitialized means the value in the variable is what ever was lying around in memory by the previous process or thread or stack. Chances are it is more likely to be 0, a small number, or a pointer to some other part of memory. – Mark Lakata Nov 12 '14 at 08:13
  • no, it is not a good idea – Ivan Ivanovich Nov 12 '14 at 09:43
  • 1
    Undefined Behavior means *anything at all could happen*. The program might crash. It might appear to work correctly. It might silently corrupt memory depending on the phase of the moon. It might erase your hard drive. It might send your mother a nasty email. It might make demons fly out of your nose. There are all permitted behaviors as far as the C language is concerned. – Adam Rosenfield Nov 13 '14 at 06:51
  • 1
    See also [Is uninitialized local variable the fastest random number generator?](http://stackoverflow.com/q/31739792/1708801) – Shafik Yaghmour Aug 05 '15 at 09:21

5 Answers5

13

No, it isn't.

Reading an uninitialized value results in undefined behavior. It can be zero, it can be semi-random — but as such, it can repeatedly be the same value. It may also cause compilation or runtime errors, or do any other completely unpredictable thing.

Then, someone else compiling your program will notice the compiler warning about uninitialized value and try to fix it. He may fix it correctly, or given complex enough program he may just initialize it to zero. That's how 'small' bugs turn into huge bugs.


Just try your snippet with srand() replaced by printf():

#include <stdio.h>

int main()
{
    {
        unsigned seed;
        printf("%u\n", seed);
    }

    return 0;
}

On my system it repeatedly gives 0. This means that there's at least one system where your code is broken :).

Michał Górny
  • 18,713
  • 5
  • 53
  • 76
  • 2
    You continue on from undefined behaviour with... "It can be zero, it can be semi-random...", but that's distracting attention from the main point - it can crash or corrupt the program behaviour - all bets are off, and not just about the initial value of `seed`. – Tony Delroy Nov 12 '14 at 09:59
  • Or [it could completely optimized away the code segment etc...](http://stackoverflow.com/a/31746063/1708801) – Shafik Yaghmour Aug 05 '15 at 09:22
8

No, accessing uninitialized variable is an undefined behavior. You should prefer time(NULL). Uninitialized variable method may introduce difficult to find bugs or may blow the computer.

Most of the time, effect observed would be, (on most implementation) above code would take (read) some leftover value from the stack that may be zero or something else but may be same on multiple runs defeating your purpose. time on the other hand is promising.

Mohit Jain
  • 30,259
  • 8
  • 73
  • 100
5

It's not a good idea. Undefined behaviour doesn't guarantee that you won't get the same seed on every run, which would be bad for randomness. It doesn't guarantee that your processor won't halt and catch fire either.

eerorika
  • 232,697
  • 12
  • 197
  • 326
2

Another point is that uninitialized variables can result in a vulnerability. So it is not only bad design and undefined behaviour, it also can make your program exploitable.

Consider this code:

#include <stdio.h>
#include <time.h>

void print_uninitialized(void) {
    unsigned var;
    printf("%u\n", var);
}

void fake_init() {
    unsigned var=42;
}

int main(void) {
    print_uninitialized();
    fake_init();
    print_uninitialized();
}

Possible output:

0
42

The next example is a bit more realistic:

#include <stdio.h>

unsigned uninitialized( void ) {
    unsigned var;
    return var;
}

unsigned square(unsigned arg){
    unsigned result=arg*arg;
    return result;
}

int main( void ) {
    unsigned to_square;
    printf("UNINITIALIZED = %u\n", uninitialized());
    while(scanf("%u", &to_square)!=EOF){
        printf("%u * %u = %u\n", to_square, to_square, square(to_square));
        printf("UNITNITIALIZED = %u\n", uninitialized());
    }
}

The uninitialized variable can be modified by a user.

Input:

2

Output:

UNINITIALIZED = 0
2 * 2 = 4
UNITNITIALIZED = 4
code monkey
  • 2,094
  • 3
  • 23
  • 26
  • 1
    [Another, IMO more realistic, example of exploitable code, relying on uninitialized variable](http://rextester.com/GCAVM19466). When compiled with no optimizations, user can control the value of uninitialized varaible. – GingerPlusPlus Nov 12 '14 at 17:34
0

In the first case there are two possibilities:

  • seed is a random variable (less possible)
  • seed is constant on every run (more possible)

time(NULL) returns the time of the system which is 99.99% different every time you run the code.

Nothing is perfect random, but using time(NULL) gives you a "more random" number then if you would use the first approach.

You should check function's usage http://www.cplusplus.com/reference/cstdlib/srand/

yonutix
  • 1,964
  • 1
  • 22
  • 51