I stores the just calculated new internal value, before computation of the return value.
So (*alpha=beta) occuring inside a line of "maths" takes a copy of beta's value and puts it as a value in to the address which alpha points to, before continuing the maths which operates upon that value of beta?
Never knew abut that, interesting trick to write lines more compactly.
Thanks
It's called operator precedence.
Bear in mind three things...
- Your method of analysis is flawed. The compiler and optimizer see the code far differently than you do.
- "Undefined behavior" can include the compiler and optimizer not just the running program.
- The only way to answer your question is to compile your program, disassemble it, then analyze the machine instructions. Which depends on the compiler version, the specific compiler options, and the precise source code used. Change any of those and the analysis has to be repeated.
Ahhh.... so there's a little OCD involved here?
So how about implementing your own random() function using a LFSR or combination of multiple LFSRs? Those can be cycled very quickly and occupy minimal storage. Also, since you don't require all the flexibility of the Arduino random() function, you can cut down the overhead drastically.
check - GitHub - RobTillaart/randomHelpers: Arduino library for faster generation of random numbers.
it implements a Marsaglia pseudo random generator.
Needs two seeds <> 0.
The helper functions use an internal buffer of random bits, so if you only need 8 bits
you can extract 4 bytes with one call to Marsaglia.
||/*|
|---|---|
|| * Compute x = (7^5 * x) mod (2^31 - 1)|
|| * wihout overflowing 31 bits:|
|| * (2^31 - 1) = 127773 * (7^5) + 2836|
|| * From Random number generators: good ones are hard to find,|
|| * Park and Miller, Communications of the ACM, vol. 31, no. 10,|
|| * October 1988, p. 1195.|
|| */|
Wow. I expected an LFSR.
If the random number needed in your ISR is less critical, I'd just find/write a separate and faster random number generator that was "good enough." (if 50us is too long to block at the main program level, isn't it also too long to have in the ISR?)
- "Undefined behavior" can include the compiler and optimizer not just the running program.
In this case there is no "undefined behavior" at the compiler/optimizer level. It's a library function, and the ways that it can fail ARE "well defined" by the ABI conventions. Non-atomic update of the seed. The possible damage is very limited...
Limited specifically, to my understanding at this point, to causing unpredictable changes to the values returned by random and the value of the random seed variable kept as a static in the background?
As far as timings go, I'm looking at like 50ms to run the main loop, but possible interrupt events maybe every 500us. And the really crucial thing is to enter the interrupt within a few us of it being triggered by a pin change. So 50us delay caused by calling random() as the LAST thing in the interrupt is a lot more acceptable for this use-case than a 50us period in the main loop in which interrupts would be forbidden (and any interrupt triggered during that time might have it's actual start thereby delayed by up to 50us).
All thoughts summed up though, it might be nice for future extensions to my code, but isn't critical, if I could have random() still work "normally" as a PRNG source, possibly useful in future developments upon what I'm doing right now. So I am starting to think about avoiding use of arduino's (avr-libc underneath) supplied random function and see about random_r with my own pointer or an alternative randomness generator method. So I think I'll look at whether alternative randomness or random_r can be done without major flash and SRAM usage increases, if so I'll do them, if not I guess I'm ok sticking with random() being used in both the loop and interruptand runing the risk that sometimes a PRNG becomes truly random (not a problem with the current use-case).
Im really curious about what your program does.
That seems incredibly slow, I would be very surprised if it's not possible to improve that by a factor of at least 10.
The risk is that random will toggle between two values. While unlikely, that is a possibility.
It's not really possible that concurrency failures occur EVERY call to random()...
The point is that "undefined behavior" is precisely that.
I'll repeat. I don't believe that there is any compile-time "undefined behavior", so there is no opportunity for the compiler/optimizer to do something weird.
There is a potential race condition at runtime, but its probability and behavior is understandable (probably even predictable in a worst-case scenario sort of way.)
Reads in an unusual clocked multi-wire serial protocol, one which is too fast to have an interrupt every time the clock line toggles. But the first bit of a message is longer than the rest, long enough to let an interrupt start and then poll (with timeouts so it won't poll forever if the message cuts off) to catch the other clock line changes. The protocol is electrically incompatible with SPI and I2C, so I can't make use of their hardware features. The randomness is because sometimes a random reply byte is needed. It is working, and was at the start of this thread, but I opened this thread wanting to make sure I hadn't done something with random() that would cause serious bugs.
I've used a XOR shift based random function now, thanks for the variety of alternative randomness generation examples. Actually uses less flash, and the same SRAM, as using arduino's random().