1

Let's say that roughly every fourth build I want to generate compiler warning, probably using #warning or maybe conditionally declaring something like int x = 3.14; which ought to generate an overflow warning.

How could I do that, using only the predecessor?

Some of these questions look good, but I can't see how to generate a random number between and 4 or to take the modulus of the large numbers which they generate:

How can I generate unique values in the C preprocessor?

How to generate a series of random numbers with the C/C++ preprocessor

Generate a random number using the C Preprocessor


[Update] I forgot to say that I am constrained to C++ 2003 :-(

I took the answer from Generate a random number using the C Preprocessor and just added

#if KISS / 4 == 1
#warning Danger, Will Robinson!
#endif

but then I get

../test/main.cpp:105:5: error: token "=" is not valid in preprocessor expressions

Referring to the line

#if KISS / 4 == 1

Where KISS expands to

(((((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)))

So, it looks like I need a different solution

Community
  • 1
  • 1
Mawg says reinstate Monica
  • 38,334
  • 103
  • 306
  • 551

1 Answers1

2

It's not entirely clear what the problem is.

The solution you have tried will not work because it is a macro-built method of generating C code that generates a pseudo random number sequence, for use in blocks of C code. The generated code contains assignments to C variables and for that reason of course is illegal within preprocessor directives: the preprocessor does not have variables or assignments.

You say you don't know how to take the modulus 4 of a large random number, using the preprocessor, even assuming you can get one in a preprocessor directive, and perhaps this difficulty is illustrated by:

#if KISS / 4 == 1

That is not how to get the modulus 4 of KISS: it is equivalent to

#if KISS == 4

KISS modulo 4 is KISS % 4 and the way to test in a preprocessor directive if KISS is a multiple of 4 is:

#if (KISS) % 4 == 0

The question title mentions no requirement that the random value should be generated using the preprocessor only, but within the post you ask how it can be done using only the preprocessor. If the objective is simply to generate a compiler warning roughly one time in 4 then I cannot see why the preprocessor alone should be used to achieve this and I lean to the view that you have wrongly concluded that it must be from the fact that the compiler warning must be triggered by a some preprocessor #if-test.

The obvious course is to have your build process - make or whatever - generate a random number with a range of 4 and pass this value as a commandline macro definition to the compilation of the source file in which the warning is to be sporadically generated.

You don't say what operating system you are working on, but to illustrate for ubuntu using shuf as the RNG:

main.cpp

#if (FORTUNE) % 4 == 0
#warning Whoops!
#endif

int main()
{
    return 0;
}

Some builds:-

$ g++ -DFORTUNE=$(shuf -i 1-4 -n 1) main.cpp
main.cpp:2:2: warning: #warning Whoops! [-Wcpp]
 #warning Whoops!
  ^
$ g++ -DFORTUNE=$(shuf -i 1-4 -n 1) main.cpp
$ g++ -DFORTUNE=$(shuf -i 1-4 -n 1) main.cpp
main.cpp:2:2: warning: #warning Whoops! [-Wcpp]
 #warning Whoops!
  ^
$ g++ -DFORTUNE=$(shuf -i 1-4 -n 1) main.cpp
$ g++ -DFORTUNE=$(shuf -i 1-4 -n 1) main.cpp
main.cpp:2:2: warning: #warning Whoops! [-Wcpp]
 #warning Whoops!
  ^
$ g++ -DFORTUNE=$(shuf -i 1-4 -n 1) main.cpp
$ g++ -DFORTUNE=$(shuf -i 1-4 -n 1) main.cpp
$ g++ -DFORTUNE=$(shuf -i 1-4 -n 1) main.cpp
$ g++ -DFORTUNE=$(shuf -i 1-4 -n 1) main.cpp
$ g++ -DFORTUNE=$(shuf -i 1-4 -n 1) main.cpp
main.cpp:2:2: warning: #warning Whoops! [-Wcpp]
 #warning Whoops!
  ^
$ g++ -DFORTUNE=$(shuf -i 1-4 -n 1) main.cpp
$ g++ -DFORTUNE=$(shuf -i 1-4 -n 1) main.cpp
main.cpp:2:2: warning: #warning Whoops! [-Wcpp]
 #warning Whoops!
  ^

If you use that shuf command then the random value will always be in the range [1-4], so your test could simply be #if FORTUNE == 4, but the modulo test will allow you to use any other RNG.

Mike Kinghan
  • 55,740
  • 12
  • 153
  • 182