Предыстория: я использую rand()
, std::rand()
, std::random_shuffle()
и другие функции в моем коде для научных расчетов. Чтобы иметь возможность воспроизвести свои результаты, я всегда явно указываю случайное начальное число и устанавливаю его через srand()
. Это работало нормально до недавнего времени, когда я понял, что libxml2 также будет лениво вызывать srand()
при первом использовании, что было после моего раннего вызова srand()
.
Я заполнил отчет об ошибке в libxml2 о его srand()
вызове, но я получил отвечать:
Затем сначала инициализируйте libxml2. Это совершенно законный звонок из библиотеки. Не следует ожидать, что никто другой не вызовет
srand()
, а на странице руководства нигде не указано, что следует избегать многократного использованияsrand()
.
На самом деле это мой вопрос. Если общая политика такова, что каждая библиотека может / должна / будет вызывать srand()
, и я могу / могу также вызывать ее здесь и там, я действительно не понимаю, как это вообще может быть полезно. Или чем тогда rand()
полезно?
Вот почему я подумал, что общая (неписаная) политика заключается в том, что никакая библиотека никогда не должна вызывать srand()
, а приложение должно вызывать ее только один раз в начале. (Не принимая во внимание многопоточность. Думаю, в этом случае вам все равно следует использовать что-то другое.)
Я также попытался немного изучить, какие другие библиотеки на самом деле называют srand()
, но не нашел. Есть ли?
Мой текущий обходной путь - это уродливый код:
{
// On the first call to xmlDictCreate,
// libxml2 will initialize some internal randomize system,
// which calls srand(time(NULL)).
// So, do that first call here now, so that we can use our
// own random seed.
xmlDictPtr p = xmlDictCreate();
xmlDictFree(p);
}
srand(my_own_seed);
Вероятно, единственным чистым решением было бы вообще не использовать это, а использовать только мой собственный генератор случайных чисел (возможно, через C ++ 11 <random>
). Но вопрос не в этом. Вопрос в том, кто должен звонить srand()
, и если все это делают, как тогда rand()
полезно?
srand()
, просто вызываяrand()
, они также повлияют на глобальный генератор случайных чисел. - person Erich Kitzmueller   schedule 10.10.2014srand_if_not_yet_initialised()
функцию в API, но для этого уже поздно. Предпочитайте версии C ++ 11. - person Tony Delroy   schedule 10.10.2014srand()
), не работает. Их ответ - пустая болтовня, пытаясь оправдать неоправданное. В остальном: если вам нужны воспроизводимые случайные числа для научных расчетов,rand()
не оплачивает счет. Это нормально для игр или просто для игр, но не более того. В противном случае до C ++ 11 вы реализуете свои собственные, а в C ++ 11 вы используете<random>
. (Но это не позволяет разработчикам библиотеки сорваться с крючка.) - person James Kanze   schedule 10.10.2014srand()
перед инициализацией библиотеки. Или просто используйте свой собственный частный генератор случайных чисел (в этом случае они должны предоставлять средства для указания начального числа, чтобы вы могли протестировать код, использующий библиотеку). - person James Kanze   schedule 10.10.2014<random>
подойдет, если библиотека не нуждается в поддержке до C ++ 11), либо попросить пользователя предоставить его (например,std::random_shuffle
). - person James Kanze   schedule 10.10.2014rand()
. (Для большинства потребуется какой-то криптографически безопасный ГСЧ. Это означает, что ниrand()
, ни что-либо в<random>
не подходят.) - person James Kanze   schedule 10.10.2014rand
и рекомендовать новые альтернативы C ++ 11, здесь, похоже, упускается из виду то, что в многих однопоточных приложениях после вызоваsrand()
с тем же начальным значением , и с одинаковыми (если есть) внешними входами выполнение как в коде библиотеки app , так и будет полностью детерминированным. Наличие вызова библиотекиrand()
изменяет глобальное состояние, но не менее предсказуемо, чем если бы это сделал код приложения более высокого уровня; если призывы перемежаются таким же образом, никакого вреда не будет. - person Tony Delroy   schedule 10.10.2014rand
не один)? - person user541686   schedule 10.10.2014rand()
, вероятно, используется для защиты от атак с алгоритмической сложностью, а не для какой-либо серьезной криптографии. - person ninjalj   schedule 10.10.2014