I would like to generate a random number or string using the C Preprocessor ... um ... I don't even know if this is possible, but I am trying to create variables on the fly (strings would be helpful here) and assign them values (integers). So there are a few things I am trying to do but the basic question remains - can I create a random string or number using the preprocessor.
-
1In short: no. You will have to write a simple preprocessor of your own. Don't forget to design a way test your random source code. – Peter G. Mar 18 '11 at 16:59
-
1Have you seen this? http://www.ciphersbyritter.com/NEWS4/RANDC.HTM `1999-01-15 Jeff Stout` – rlb.usa Mar 18 '11 at 17:01
-
6Do you really need *random* or do you just need *unique* ? If the latter then maybe use `__LINE__` to create unique variable names ? – Paul R Mar 18 '11 at 17:29
-
1I think Paul identified what the OP really wants to do. – R.. GitHub STOP HELPING ICE Mar 18 '11 at 17:38
2 Answers
Based on 1999-01-15 Jeff Stout (thanks to @rlb.usa)
#define UL unsigned long
#define znew ((z=36969*(z&65535)+(z>>16))<<16)
#define wnew ((w=18000*(w&65535)+(w>>16))&65535)
#define MWC (znew+wnew)
#define SHR3 (jsr=(jsr=(jsr=jsr^(jsr<<17))^(jsr>>13))^(jsr<<5))
#define CONG (jcong=69069*jcong+1234567)
#define KISS ((MWC^CONG)+SHR3)
/* Global static variables:
(the seed changes on every minute) */
static UL z=362436069*(int)__TIMESTAMP__, w=521288629*(int)__TIMESTAMP__, \
jsr=123456789*(int)__TIMESTAMP__, jcong=380116160*(int)__TIMESTAMP__;
int main(int argc, _TCHAR* argv[]){
cout<<KISS<<endl;
cout<<KISS<<endl;
cout<<KISS<<endl;
}
Output:
247524236
3009541994
1129205949

- 894
- 13
- 20
-
1
-
-
@user10133158 `__TIMESTAMP__` is a compiler variable that has a 1-minute precision. So, every different minute you compile, the seed changes – nergeia Jan 29 '19 at 09:05
-
2This is misleading because it does not use the preprocessor to compute a random number, as OP requested. Instead it inserts a block of C code that will be compiled into code that computes a number. – ScottJ Aug 07 '21 at 20:10
-
-
1@nergeia Nonsense. Run it with `gcc -E` (preproccesor only) to see the result: cout<<(((((z=36969*(z&65535)+(z>>16))<<16)+((w=18000*(w&65535)+(w>>16))&65535))^(jcong=69069*jcong+1234567))+(jsr=(jsr=(jsr=jsr^(jsr<<17))^(jsr>>13))^(jsr<<5)))<
– ScottJ Aug 13 '21 at 21:47
I take your question that you want to have a way of creating unique identifier tokens through the preprocessor.
gcc has an extension that is called __COUNTER__
and does what you expect from its name. You can combine this with macro concatenation ##
to obtain unique identifiers.
If you have a C99 compiler you can use P99. It has macros called P99_LINEID
and P99_FILEID
. They can be used as
#include "p99_id.h"
P99_LINEID(some, other, tokens, to, make, it, unique, on, the, line)
and similarily for P99_FILEID
.
The first mangles a name from your tokens and the line number and a hash that depends on the number of times the file "p99_id.h" had been included. The second macro just uses that hash and not the line number such that a name is reproducible at several places inside the same compilation unit.
These two macros also have counterparts P99_LINENO
and P99_FILENO
that just produce large numbers instead of identifier tokens.

- 76,821
- 6
- 102
- 177
-
2Isn't that extension `__COUNTER__`? https://gcc.gnu.org/onlinedocs/cpp/Common-Predefined-Macros.html – Alyssa Haroldsen Aug 06 '15 at 04:28
-
1Wanted to add that `__COUNTER__` is also available for other compilers like [MSVC](https://msdn.microsoft.com/en-us/library/b0084kay.aspx). Just be aware that `__COUTER__` is only unique for the file the pre-processor is currently parsing (it starts with `0` for each source file parsed). – Florian Feb 28 '17 at 13:50