Not if you expect to be able to use the run-time value of a variable to control the number of repetitions (unless the range of values of that variable is small and known at compile-time).
Macro expansion and literal string concatenation are done as phases during the compilation, before the executable has been produced. The program doesn't yet exist, and certainly cannot be run. The macro preprocessor only sees a variable as an identifier inside the text of the program.
If you will always use a literal integer, then it is possible to do the expansion with the macro preprocessor, although it does indeed require a lot of macros. There are some macro libraries which can help.
If you know the maximum number of repetitions (and have some runtime mechanism to verify that the limit is not exceeded), you could create a single string literal of the maximum size, perhaps using a macro library as mentioned above. You can then get a string literal containing fewer than this maximum by starting int the middle:
#define Multi(literal, rep) \
(&(REP(MAXREP, literal))[((sizeof literal)-1)*(MAXREP-rep)])
For that to work, MAXREP
must be previously #define
d as a (smallish) integer constant (not a constant expression).
Here's a complete example program, using BOOST_PP_REPEAT
from the Boost preprocessor library to define REP
:
#include <stdio.h>
#include <stdlib.h>
#include <boost/preprocessor/repeat.hpp>
#define MAXREP 80
#define REPEATER(z, n, literal) literal
#define REP(n, literal) BOOST_PP_REPEAT(n, REPEATER, literal)
#define Multi(literal, rep) \
(&(REP(MAXREP, literal))[((sizeof literal)-1)*(MAXREP-rep)])
int main(int argc, char** argv) {
int reps = 0;
if (argc > 1) reps = atoi(argv[1]);
if (reps <= 0) reps = MAXREP;
if (reps > MAXREP) {
fprintf(stderr, "Cannot do %d repetitions; maximum is %d\n", reps, MAXREP);
exit(1);
}
for (int i = 0; i < reps; ++i) printf("%s\n", Multi("foo", i));
return 0;
}
Sample run:
$ make rep
cc -O0 -Wall -ggdb -std=c11 -D_XOPEN_SOURCE=700 -mtune=native rep.c -o rep
$ ./rep 5
foo
foofoo
foofoofoo
foofoofoofoo