i'm using macros to define static size for some arrays in my code, i have defined a config macro variable at the top of my code and some macro variables depend on said macro variable. i can make a function that takes that value and returns the required size of the array but that would execute in runtime and i'll need to use VLAs.
example below shows macro for SIZE of a number (with no repeating digits) and whether that number can begin with a zero ("0123" vs "1234").
code to calculate LIMIT in runtime:
int limit(int size, int npz){
l = npz ? 9 : 10;
for(int i = 1; i < size; i++)
l *= 10 - i;
return l;
}
i manually calculated the amount of said numbers for all values. is there a work around?
#define SIZE 4 // 1 .. 10
#define NO_PADDING_ZERO 1 // 1 | 0
#if NO_PADDING_ZERO
#if SIZE == 1
#define LIMIT 9
#elif SIZE == 2
#define LIMIT 81
#elif SIZE == 3
#define LIMIT 648
#elif SIZE == 4
#define LIMIT 4536
#elif SIZE == 5
#define LIMIT 27216
#elif SIZE == 6
#define LIMIT 136080
#elif SIZE == 7
#define LIMIT 544320
#elif SIZE == 8
#define LIMIT 1632960
#else
#define LIMIT 3265920
#endif
#else
#if SIZE == 1
#define LIMIT 10
#elif SIZE == 2
#define LIMIT 90
#elif SIZE == 3
#define LIMIT 720
#elif SIZE == 4
#define LIMIT 5040
#elif SIZE == 5
#define LIMIT 30240
#elif SIZE == 6
#define LIMIT 151200
#elif SIZE == 7
#define LIMIT 604800
#elif SIZE == 8
#define LIMIT 1814400
#else
#define LIMIT 3628800
#endif
#endif
The workaround could be to generate C code from something else.
Consider learning more, using GPP or your own C code generator (perhaps using GNU bison and in some simple cases GNU gawk or GNU autoconf).
Observe that on Linux or POSIX, you could generate C code, compile it as a plugin, and dlopen(3) that plugin. For a useless example, see manydl.c. For useful (but obsolete) example, see my old GCC MELT.
Another approach (GCC specific) might be to extend your compiler with GCC plugins. See bismon.
You can also generate machine code (in your program) using GNU lightning or (in C++) asmjit. Then read the Dragon book and this answer.
Read some books by Jacques Pitrat explaining that metaprogramming approach (reused in RefPerSys)
The concepts related to partial evaluation are relevant.
It's this some kind of the factorial?
(10 - NO_PADDING_ZERO) * 9 * 8 * ... * (10 - LIMIT)
You can use this in the loop expression in a macro or an inline function and the optimizing compiler will compute it at compile time.
#include <bool.h>
inline int limit(int size, bool npz){
int l = 10 - npz;
for(int i = 1; i < size; i++)
l *= 10 - i;
return l;
}
#define LIMIT (limit(SIZE, NO_PADDING_ZERO))
If you wish you may define a precomputed array and use
#define LIMIT (array[SIZE][NO_PADDING_ZERO])
Related
I'm wondering if it can be written that the prepocessor evaluates assigned constants known at compile time and returns the result as a string. I believe the answer is no or complex, but I'll give a try.
Basically I have constants which are expressed in milliseconds but I want to display the results as secs, therefore divide by 1000, and wonder because all is known at compile time, if the preprocessor can directly put the result of this division into the code rather than eval at runtime.
Example:
#define FREQ_AUTO_WHEN_RELAY_ON 150000UL
#define STR_HELPER(x) #x
#define STR(x) STR_HELPER(x)
STR( FREQ_AUTO_WHEN_RELAY_ON/1000UL ) " secs"
would yield to "150000UL/1000UL secs"
which is not I want to display, aka "150 secs"
Thanks
You have to first prepare a header with all possible outputs:
// calculate.h
#if VALUE == 1
#define RESULT 1
#elif VALUE == 2
#define RESULT 2
/* etc. millions of lines */
#elif VALUE == 150
#define RESULT 150
#endif
Then you can do:
#define VALUE FREQ_AUTO_WHEN_RELAY_ON/1000UL
#include "calculate.h"
STR(VALUE)
Similarly, you first have to define a matrix of all possible combinations of values:
#define DIV_1UL_1UL 1
#define DIV_1UL_2UL 0
#define DIV_2UL_1UL 2
/* etc. really millions of lines */
#define DIV_150000UL_1000UL 150
Then you can:
#define DIV(a, b) DIV_##a##_##b
#define XDIV(a, b) DIV(a, b)
STR(XDIV(FREQ_AUTO_WHEN_RELAY_ON, 1000UL))
Can C-preprocessor can output as a string the evaluation of compiled known constants values(e.g. 150000UL/1000UL)?
Yes, but it's not practical. Instead, generate the header file from a build system.
On my system, I have a /usr/include directory, with a curl/options.h file in it, which contains a preprocessor definition of CURLOT_FLAG_ALIAS.
If I have the following test.txt:
#include "curl/options.h"
curlot flag alias is: CURLOT_FLAG_ALIAS
Then I can do this to expand the macro in the text file:
$ gcc -E -P -x c -I/usr/include test.txt
typedef enum {
CURLOT_LONG,
CURLOT_VALUES,
CURLOT_OFF_T,
CURLOT_OBJECT,
CURLOT_STRING,
CURLOT_SLIST,
CURLOT_CBPTR,
CURLOT_BLOB,
CURLOT_FUNCTION
} curl_easytype;
struct curl_easyoption {
const char *name;
CURLoption id;
curl_easytype type;
unsigned int flags;
};
CURL_EXTERN const struct curl_easyoption *
curl_easy_option_by_name(const char *name);
CURL_EXTERN const struct curl_easyoption *
curl_easy_option_by_id(CURLoption id);
CURL_EXTERN const struct curl_easyoption *
curl_easy_option_next(const struct curl_easyoption *prev);
curlot flag alias is: (1<<0)
However, this approach also dumped all the function definitions in curl/options.h; ultimately, to just process the text file, this gives a much "cleaner" result - have test.txt be just:
curlot flag alias is: CURLOT_FLAG_ALIAS
... and then use -imacros switch (and pipe into grep to remove empty lines):
$ gcc -E -P -x c -I/usr/include -imacros curl/options.h test.txt | grep -v '^[[:space:]]*$'
curlot flag alias is: (1<<0)
Great - except, I do not really want the (1<<0) in the text output - I want its expanded integer decimal value, 1; in other words, I'd want the text output to be:
curlot flag alias is: 1
I guess one way would be, to keep the original and modified text file, identify range of characters in the modified file of the parts that are changed from the original file, here (1<<0) - then feed that string into some calculator, then replace it with the output of the calculator. However, while (1<<0) is parseable by calculators like wcalc - I doubt many common idioms like (1u<<32) would be parseable by it, so even strings like these would have to go through the compiler I guess, and the C compiler is not REPL, so it cannot "just" give a value for an input like (1<<0) ...
Now, I'm aware the C preprocessor does not do arithmetic, apart from conditionals ( Can the C preprocessor perform integer arithmetic? ), so maybe what I want to achieve is impossible with C preprocessor (and possibly compiler) - if that is the case, are there any other tools to help me achieve replacement and expansion of C macros with integer arithmetic in a text file?
One common approach is to actually compile and execute the code instead of merely preprocessing it. Have a file make_test.c containing:
#include <stdio.h>
#include "curl/options.h"
int main(void) {
printf("curlot flag alias is: %d\n", CURLOT_FLAG_ALIAS);
return 0;
}
and then have your build process compile and execute this program.
gcc -o make_test -I /usr/include make_test.c
./make_test
Yes, you can extract the result of evaluating an integer constant expression using a system commonly referred to as preprocessor slots:
slot.h:
// slot.h
#define DIG DIG_CATe(DIG_2,DIG_1)
#define DIG_CATe(a,b) DIG_CAT(a,b)
#define DIG_CAT(a,b) a##b
#undef DIG_1
#if (SLOT) % 10 == 0
#define DIG_1 0
#elif (SLOT) % 10 == 1
#define DIG_1 1
#elif (SLOT) % 10 == 2
#define DIG_1 2
#elif (SLOT) % 10 == 3
#define DIG_1 3
#elif (SLOT) % 10 == 4
#define DIG_1 4
#elif (SLOT) % 10 == 5
#define DIG_1 5
#elif (SLOT) % 10 == 6
#define DIG_1 6
#elif (SLOT) % 10 == 7
#define DIG_1 7
#elif (SLOT) % 10 == 8
#define DIG_1 8
#elif (SLOT) % 10 == 9
#define DIG_1 9
#endif
#undef DIG_2
#if (SLOT/10) % 10 == 0
#define DIG_2 0
#elif (SLOT/10) % 10 == 1
#define DIG_2 1
#elif (SLOT/10) % 10 == 2
#define DIG_2 2
#elif (SLOT/10) % 10 == 3
#define DIG_2 3
#elif (SLOT/10) % 10 == 4
#define DIG_2 4
#elif (SLOT/10) % 10 == 5
#define DIG_2 5
#elif (SLOT/10) % 10 == 6
#define DIG_2 6
#elif (SLOT/10) % 10 == 7
#define DIG_2 7
#elif (SLOT/10) % 10 == 8
#define DIG_2 8
#elif (SLOT/10) % 10 == 9
#define DIG_2 9
#endif
// ...
#undef SLOT
test.c:
#define SLOT 2*5
#include "slot.h"
result 1: DIG
#define SLOT (1+3*4)*2
#include "slot.h"
result 2: DIG
output (cc -P -E):
result 1: 10
result 2: 26
Although the utility of using this for your problem is questionable.
So I'm trying to create an implementation of an algorithm that uses fixed-width integers. That being said I want to use the largest size available, and at the same time need to know the number of bits in it, as the algorithm relies on bit shifting.
I would like a way, preferably via pre-processor, to determine the width of the largest integer type (currently I'm using uintmax_t from stdint.h), but failing that I could exhaustively achieve this if I know the fixed-width types that are defined/supported by the compiler.
I found an old program on my PC where I have the pre-processor directives of #ifdef __INT64_TYPE__, which would be passable, but I have no idea where these would be defined, or under what standards.
So to sum up, if anyone knows a way to count the number of bits in uintmax_t, that'd be perfect, but failing that where have I got __INT64_TYPE__ from?
if anyone knows a way to count the number of bits in uintmax_t, that'd be perfect, but failing that where have I got INT64_TYPE from?
To count the number of bit in an unsigned type is easy. Set to -1 and count the number of shift until 0.
int bc_uintmax_t(void) {
int bc = 0;
uintmax_t x = -1;
while (x) {
x %= 2;
bc++;
}
return bc;
}
To portable detect the number of bits in uintmax_t at compile time is harder. A chief obstacle is the pre-preprocessor arithmetic may only work up to intmax_t. So unless some assumptions are made, a portable solution may be unfindable.
Of course sizeof (uintmax_t) * CHAR_BIT is the maximum possible bit width that type could have. Yet padding bits could occur.
Look for (u)intmax_t and Exact-width integer types like uint64_t in <stdint.h>.
[Edit]
To determine the value bit width of a constant at compile time, code could use the following. Note: With UINTMAX_MAX, I am not certain how portable is this code.
#include <stdio.h>
#include <limits.h>
#define ISGE2_1(x) ((x) >= 2)
#define ISGE2_2(x) ((x) >= 4)
#define ISGE2_4(x) ((x) >= 16)
#define ISGE2_8(x) ((x) >= 256)
#define ISGE2_16(x) ((x) >= 65536)
#define ISGE2_32(x) ((x)/65536 >= 65536)
#define ISGE2_64(x) ((x)/4294967296 >= 4294967296)
#define ISGE2_128(x) ((x)/18446744073709551616 >= 18446744073709551616)
#define BW_1ORLESS(x) ((x) ? 1 : 0)
#define BW_2ORLESS(x) (ISGE2_1(x) ? 1 + BW_1ORLESS(x/2) : BW_1ORLESS(x))
#define BW_4ORLESS(x) (ISGE2_2(x) ? 2 + BW_2ORLESS(x/4) : BW_2ORLESS(x))
#define BW_8ORLESS(x) (ISGE2_4(x) ? 4 + BW_4ORLESS(x/16) : BW_4ORLESS(x))
#define BW_16ORLESS(x) (ISGE2_8(x) ? 8 + BW_8ORLESS(x/256) : BW_8ORLESS(x))
#define BW_32ORLESS(x) (ISGE2_16(x) ? 16 + BW_16ORLESS(x/65536) : BW_16ORLESS(x))
#define BW_64ORLESS(x) (ISGE2_32(x) ? 32 + BW_32ORLESS(x/4294967296) : BW_32ORLESS(x))
#define BW_128ORLESS(x) (ISGE2_64(x) ? 64 + BW_64ORLESS(x/18446744073709551616) : BW_64ORLESS(x))
#if INTMAX_MAX/4294967296 > 4294967296
#define BW_65PLUS(x) (ISGE2_128(x) ? BW_129PLUS(x) : BW_128ORLESS(x))
#define BIT_WIDTH_POSITIVE_VALUE(x) (ISGE2_64(x) ? BW_65PLUS(x) : BW_64ORLESS(x))
#else
#define BW_33PLUS(x) (ISGE2_64(x) ? BW_65PLUS(x) : BW_64ORLESS(x))
#define BIT_WIDTH_POSITIVE_VALUE(x) (ISGE2_32(x) ? BW_64ORLESS(x) : BW_32ORLESS(x))
#endif
// Do not call BIT_WIDTH_POSITIVE_VALUE with negative values.
Application
#include <limits.h>
#include <stdbool.h>
#include <stdlib.h>
int main() {
printf("%d\n", BIT_WIDTH_POSITIVE_VALUE(true));
printf("%d\n", BIT_WIDTH_POSITIVE_VALUE(CHAR_BIT));
printf("%d\n", BIT_WIDTH_POSITIVE_VALUE(SCHAR_MAX));
printf("%d\n", BIT_WIDTH_POSITIVE_VALUE(SHRT_MAX));
printf("%d\n", BIT_WIDTH_POSITIVE_VALUE(INT_MAX));
printf("%d\n", BIT_WIDTH_POSITIVE_VALUE(LONG_MAX));
printf("%d\n", BIT_WIDTH_POSITIVE_VALUE(LLONG_MAX));
printf("%d\n", BIT_WIDTH_POSITIVE_VALUE(INTMAX_MAX));
printf("%d\n", BIT_WIDTH_POSITIVE_VALUE(UINTMAX_MAX));
return 0;
}
Output
1
4
7
15
31
31
63
63
64
I've used things like
#if (UINTMAX_MAX > 0xFFFFFFFFFFFFFFF5ULL)
etc.
I have structure like below
typedef struct
{
int a;
int b;
int c;
} my_struct;
and in another file I have declared a variable of this my_struct type, like below.
my_struct strct_arr[MAX];
Where MAX is a macro which is a configurable value that is a multiple of 18 (18 or 36 or 54 and so on.. it may go up to 18*n times).
I have to initialize the structure with {0xff,0,0}. So, how to initialize whole array of structure my_struct strct_arr[MAX]; with my initial values without using any kind of loops.
I am expecting the output as below:
my_struct strct_arr[MAX]={
{0xff,0,0},
{0xff,0,0},
{0xff,0,0},
{0xff,0,0},
…
};
But without knowing MAX value, how to initialize it?
There is GCC extension for this. Try this
#define MAX 18
my_struct strct_arr[MAX]={ [0 ... (MAX - 1)] = {0xff,0,0}};
Check https://gcc.gnu.org/onlinedocs/gcc-4.2.1/gcc/Designated-Inits.html
Yes, this is possible using the C preprocessor!
#include <stdio.h>
#include <boost/preprocessor/repetition/repeat.hpp>
#define INITS(z, n, t) { 0xFF, 0, 0 },
#define REP(item, n) BOOST_PP_REPEAT(n, INITS, item)
#define MAX 123
typedef struct { int a,b,c; } my_struct;
my_struct ms[] = { REP(, MAX) };
int main()
{
// Check it worked
printf("%d\n", (int)(sizeof ms / sizeof *ms));
}
Note: boost is a package of C++ stuff, however the boost/preprocessor just uses the preprocessor features which are common to both languages. If your implementation doesn't allow this #include by default, you can find a copy of repeat.hpp from the boost source code.
Also, BOOST_PP_REPEAT defaults to a max of 256. If your MAX is bigger than this, you can edit repeat.hpp to allow bigger values, it should be obvious what to do from there.
Note: this post describes a system for recursive macro that would not require the same sort of implementation as repeat.hpp uses, but I haven't been able to get it to work.
Credit: this post
Well, there's is no direct and immediate syntax in standard C to specify an initializer that would do what you want. If you wanted to initialize the whole thing with zeros, then = { 0 } would work regardless of size, but that 0xff makes it a completely different story. GCC compiler supports a non-standard extension that works in such cases (see Sanket Parmar's answers for details), but alas it is not standard.
There's also a non-standard memcpy hack that is sometimes used to fill memory regions with repetitive patterns. In your case it would look as follows
my_struct strct_arr[MAX] = { { 0xff, 0, 0 } };
memcpy(strct_arr + 1, strct_arr, sizeof strct_arr - sizeof *strct_arr);
But this is a hack, since it relies on memcpy doing its copying in byte-by-byte fashion and in strictly left-to-right direction (i.e. from smaller memory addresses to larger ones). However, that's not guaranteed by the language specification. If you want to "legalize" this trick, you have to write your own version of my_memcpy that works in that way specifically (byte-by-byte, left-to-right) and use it instead. Of course, this is formally a cyclic solution that is not based entirely on initializer syntax.
Paraphrasing Jonathan Leffler's solution:
struct my_struct { char c, int a; int b; }
#define MAX 135
#define INIT_X_1 { 0xff, 0, 0 }
#define INIT_X_2 INIT_X_1, INIT_X_1
#define INIT_X_4 INIT_X_2, INIT_X_2
#define INIT_X_8 INIT_X_4, INIT_X_4
#define INIT_X_16 INIT_X_8, INIT_X_8
#define INIT_X_32 INIT_X_16, INIT_X_16
#define INIT_X_64 INIT_X_32, INIT_X_32
#define INIT_X_128 INIT_X_64, INIT_X_64
struct my_struct strct_arr[MAX] =
{
#if (MAX & 1)
INIT_X_1,
#endif
#if (MAX & 2)
INIT_X_2,
#endif
#if (MAX & 4)
INIT_X_4,
#endif
#if (MAX & 8)
INIT_X_8,
#endif
#if (MAX & 16)
INIT_X_16,
#endif
#if (MAX & 32)
INIT_X_32,
#endif
#if (MAX & 64)
INIT_X_64,
#endif
#if (MAX & 128)
INIT_X_128,
#endif
};
Just for sake of variety, since you know the array will be a multiple of 18, you could use something like this:
#define INIT_X_1 { 0xff, 0, 0 }
#define INIT_X_3 INIT_X_1, INIT_X_1, INIT_X_1
#define INIT_X_9 INIT_X_3, INIT_X_3, INIT_X_3
#define INIT_X_18 INIT_X_9, INIT_X_9
my_struct strct_arr[MAX] =
{
INIT_X_18,
#if MAX > 18
INIT_X_18,
#if MAX > 36
INIT_X_18,
#endif
#endif
};
This will work without needing C99 support (it would even work with pre-standard C), GCC extensions, or Boost Preprocessor library. In every other respect, the other solutions are better.
I has implemented own tmpnam() function for creating temporary files. I use following defines for adjust this one:
/* The length of random string. In /tmp/test143276 is 143246 */
#define RND_ROUND 6
/* Used as a minimal bound produced by number generator */
#define RND_MIN 100000
/* Used as a maximum bound produced by number generator */
#define RND_MAX 1000000
As you can see the real needed macro is RND_ROUND and others are derivative to pass to the number generator. And the formula for generating is:
RND_MIN = 1 and [RND_ROUND-1] zeros
RND_MAX = 1 and [RND_ROUND] zeros
Question: How can I create some macro which will produce RND_MIN and RND_MAX based on RND_ROUND at compile time?
Example:
#define RND_ROUND 6
// somehow define those RND_MIN and RND_MAX
...
int32_t random = g_rand_int_range(generator, RND_MIN(RND_ROUND), RND_MAX(RND_ROUND));
You can use the power function to do the work.
#define RND_MIN (pow (10, RND_ROUND-1))
#define RND_MAX (pow (10, RND_ROUND))
Or depending on the passed argument.
#define RND_MIN(val) (pow (10, (val)-1))
#define RND_MAX(val) (pow (10, (val)))
If I am correct you can use power function:
#define RND_MIN(RND_ROUND) pow(10, RND_ROUND - 1)
#define RND_MAX(RND_ROUND) pow(10, RND_ROUND)
You may like to read: How to simplify this power equation?
I would suggest you to forget about RND_ROUND: this is compile time, anyway!
#define RND_BASE 1000000
#define RND_MIN RND_BASE
#define RND_MAX (RND_BASE*10)
Now, if you really need RND_ROUND, RND_MIN and RND_MAX at compile time and not being expanded to pow, assuming your RND_ROUND is not you may branch it with #if (note that g_rand_int_range is limited to gint32, so RND_MAX<2^31=2'147'483'648<10^10 is possible):
#if RND_ROUND <= 1
# define RND_MIN 1
#elif RND_ROUND <= 2
# define RND_MIN 10
#elif RND_ROUND <= 3
# define RND_MIN 100
#elif RND_ROUND <= 4
# define RND_MIN 1000
#elif RND_ROUND <= 5
# define RND_MIN 10000
#elif RND_ROUND <= 6
# define RND_MIN 100000
#elif RND_ROUND <= 7
# define RND_MIN 1000000
#elif RND_ROUND <= 8
# define RND_MIN 10000000
#else
# define RND_MIN 100000000
#endif
#define RND_MAX (RND_MIN*10)
This will also be safer, limiting RND_ROUND so that there will not be integer overflows.