Network programmers of a certain age may remember the Windows Sockets Lame List.
I previously wrote a short “don’t-do-that-do-this” guide for modern C++ randomness, and I was recently reading another Reddit exchange featuring STL, author of many parts of Microsoft’s STL implementation, when it struck me that use of C++ <random>
needs its own lame list to discourage using the old and busted C parts and encourage the using the new C++ hotness. So here, in no particular order, and with apologies to Keith Moore (wherever he may be) is an incomplete lame list for use of <random>
.
- Calling
rand()
orsrand()
. Lame. - Using
time(NULL)
to seed an RNG. Inexcusably lame. - Claiming, “But
rand()
is good enough for simple uses!” Dog lame. - Using
random_shuffle()
to permute a container. Mired in a sweaty mass of lameness. - Using
default_random_engine
. Nauseatingly lame. - Using
%
to get a random value in a range. Lame. Lame. Lame. Lame. Lame. - Not using
random_device
to seed an RNG. Violently lame. - Assuming that
random_device
is going to do the right thing on your platform. Uncontrollably lame. - Failing to handle a possible exception from the construction or use of
random_device
. Totally lame. - Using anything in the standard but
mt19937
ormt19937_64
as a generator. Intensely lame. - Putting
mt19937
on the stack. In all my years of observing lameness, I have seldom seen something this lame. - Seeding
mt19937
with only one 32-bit word rather than its fullstate_size
. Pushing the lameness envelope. - Forgetting that
uniform_int_distribution
works on a closed interval. Thrashing in a sea of lameness. - Passing
random_device
or a generator togenerate_n()
by value, forgetting to wrap it withref()
. Glaringly lame. - Failing to use
seed_seq
to initialize a generator’s state properly. Indescribably lame. - Not considering thread safety when using a generator. Floundering in an endless desert of lameness.
- Using a global generator without making it
thread_local
. Suffocating in self lameness. - Using
RAND_MAX
instead ofmt19937::max()
. Perilously teetering on the edge of a vast chasm of lameness.
This list will undoubtedly grow as I continue to write lame code…
Fun post XD
I don’t understand, why not constructing the generator on the stack?
Because it’s large and expensive to construct. 624 32-bit words of state.
If you mean that having a 2504 byte stack frame is not a good idea, I agree.
Raw performance is not affected, however.
The blog post itself is lame. It doesn’t say absolutely anything why any of the use cases above are bad. Could be an interesting information for those new in the area.
The Windows Sockets lame list offered some explanations at least.
One more note: the link http://www.elbeno.com/blog/?p=1081 seems to be down, BTW
Re Nicola: sure, but a generator on the stack implies it’s going to be re-initialized every time through the function.
Re Adi: I saw that the WSLL had explanations added later on, but I decided to a) keep the list a list and not a TL;DR article, b) hopefully inspire people to research and understand the why themselves.
There’s plenty already written about this elsewhere, I just thought this was a bit of fun.
(And the link seems fine? Must have been some transient issue.)
This list lacks the reason + alternatives that make the Winsock lame list fairly useful. Instead this article makes assumptions that the reader is already informed on the reasons why these things are lame and subsequently isn’t very helpful.