Is it good idea to pass uninitialized variable to

2019-02-25 04:15发布

问题:

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;
}

回答1:

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 :).



回答2:

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.



回答3:

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.



回答4:

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


回答5:

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/



标签: c++ c srand