Это хорошая идея передать неинициализированную переменную в srand?

Хорошо ли передать неинициализированную переменную в srand вместо результата time(NULL)?
Это один #include, а один вызов функции меньше.

Пример кода:

#include <stdlib.h>

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

вместо

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

int main(void) {
    srand(time(NULL));
    //other code
    return 0;
}

Ответ 1

Нет, это не так.

Чтение неинициализированного значения приводит к поведению undefined. Он может быть нулевым, он может быть полуслучайным, но как таковой он может неоднократно быть одним и тем же значением. Это может также привести к ошибкам компиляции или времени выполнения или любой другой совершенно непредсказуемой вещи.

Затем кто-то другой, компилирующий вашу программу, заметит предупреждение компилятора о неинициализированном значении и попытается его исправить. Он может исправить это правильно или получить достаточно сложную программу, он может просто инициализировать ее до нуля. То, что "маленькие" ошибки превращаются в огромные ошибки.


Просто попробуйте свой фрагмент с заменой srand() на printf():

#include <stdio.h>

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

    return 0;
}

В моей системе она несколько раз дает 0. Это означает, что существует хотя бы одна система, где ваш код сломан:).

Ответ 2

Нет, доступ к неинициализированной переменной - это поведение undefined. Вы должны предпочесть time(NULL). Неинициализированный метод переменной может затруднить поиск ошибок или может привести к выходу компьютера из строя.

В большинстве случаев наблюдаемый эффект будет (при большей реализации) выше кода будет принимать (читать) некоторое оставшееся значение из стека, которое может быть нулевым или чем-то другим, но может быть одинаковым во многих прогонах, побеждающих вашу цель. time, с другой стороны, обещает.

Ответ 3

Это не очень хорошая идея. Поведение Undefined не гарантирует, что вы не получите одно и то же семя при каждом прогоне, что было бы плохо для случайности. Это не гарантирует, что ваш процессор не остановится и не загорится.

Ответ 4

Другим моментом является то, что неинициализированные переменные могут привести к уязвимости. Таким образом, это не только плохой дизайн и поведение undefined, он также может сделать вашу программу доступной.

Рассмотрим этот код:

#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();
}

Возможный выход:

0
42

Следующий пример является более реалистичным:

#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());
    }
}

Неинициализированная переменная может быть изменена пользователем.

Input:

2

Вывод:

UNINITIALIZED = 0
2 * 2 = 4
UNITNITIALIZED = 4

Ответ 5

В первом случае возможны две возможности:

  • семя - это случайная величина (менее возможно)
  • семя постоянно в каждом прогоне (возможно)

time (NULL) возвращает время, равное 99.99% при каждом запуске кода.

Ничто не является идеальным случайным, но использование времени (NULL) дает вам "более случайный" номер, если вы будете использовать первый подход.

Вы должны проверить использование функции http://www.cplusplus.com/reference/cstdlib/srand/