17

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.

4
  • 1
    In 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.
    Commented Mar 18, 2011 at 16:59
  • 1
    Have you seen this? ciphersbyritter.com/NEWS4/RANDC.HTM 1999-01-15 Jeff Stout
    – rlb.usa
    Commented Mar 18, 2011 at 17:01
  • 6
    Do you really need random or do you just need unique ? If the latter then maybe use __LINE__ to create unique variable names ?
    – Paul R
    Commented Mar 18, 2011 at 17:29
  • 1
    I think Paul identified what the OP really wants to do. Commented Mar 18, 2011 at 17:38

2 Answers 2

22

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
6
  • 1
    Very good implementation for an embedded system. Both answers are good.
    – Xofo
    Commented May 27, 2015 at 17:45
  • What does it mean: "the seed changes on every minute"? What event changes it?
    – user10133158
    Commented Oct 18, 2018 at 15:14
  • @user10133158 __TIMESTAMP__ is a compiler variable that has a 1-minute precision. So, every different minute you compile, the seed changes
    – nergeia
    Commented Jan 29, 2019 at 9:05
  • 2
    This 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
    Commented Aug 7, 2021 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)))<<endl;
    – ScottJ
    Commented Aug 13, 2021 at 21:47
16

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.

2
  • 2
    Isn't that extension __COUNTER__? gcc.gnu.org/onlinedocs/cpp/Common-Predefined-Macros.html Commented Aug 6, 2015 at 4:28
  • 1
    Wanted to add that __COUNTER__ is also available for other compilers like MSVC. 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
    Commented Feb 28, 2017 at 13:50

Not the answer you're looking for? Browse other questions tagged or ask your own question.