How to make a variable value passage for preprocessor? - c

Here I know that the following code simply copies the character i rather than its value to the preprocessor statement (which makes a error for undefined symbol i in compile-time).
What I want is:
Is their a way such that the compiler treats, i as a variable with some value rather than a character ?
#include <stdio.h>
#define PRINT(x) printf("%d \n", y ## x)
int main(void) {
int y1=0 , y2=1 , y3=4;
for(int i=1; i <= 3; ++i) {
PRINT(i);
}
return 1;
}

About the pre-processor
First of all, I think there's a need to clarify how the preprocessor works: it pre-processes the input files, which means it runs before the compiler. Unfortunatly, for historical reasons, it doesn't know anything about C or C++, doesn't parse anything, and just does very simple textual operations on words and parenthesis. Just to illustrate my point:
#define this __FILE__
#define file -- Hell no!
#define fine(a, b) fine: a ## _ ## b
Ok, so this is not a valid C or C++ file
But the preprocessor will run just fine(go, try!)
Run this with a pre-processor, for example gcc -x c -E -P test.txt and you'll get:
Ok, so "test.txt" is not a valid C or C++ -- Hell no!
But the preprocessor will run just fine: go_try!
So, obviously, when the preprocessor sees PRINT(i) in your code, it replaces it with printf("%d \n", yi) without thinking much about it. And it has absolutely no idea i is a variable, don't even think about evaluating it's value.
Solutions
Basically, what you want is print a bunch of numbers.
You could simply do
printf("0\n1\n4\n");
But this lacks makes changing numbers cumbersome,
so let's go with
printf("%d\n%d\n%d\n", 0, 1, 4);
Which makes it easy to change a number, but not to add/remove one.
Ok so how about:
printf("%d\n", 0);
printf("%d\n", 1);
printf("%d\n", 4);
Yeah, you can change/add/remove numbers easily but as any sane programmer you hate repetition. So, we need some kind of loop.
By far the simplest and most straightforward way to iterate in C is at runtime, using an array:
int [] y = { 0, 1, 4 };
for(int i = 0; i < sizeof(y)/sizeof(int); ++i) {
printf("%d\n", y[i]);
}
If you want, you can hide the printf using a function:
inline void print_int(int* y, int i) { print_int(y[i]); }
int [] y = { 0, 1, 4 };
for(int i = 0; i < sizeof(y)/4; ++i) print_int(y, i);
And going further with functions:
inline void print_int(int x) { printf("%d\n", x); }
inline void print_int(int* y, int i) { print_int(y[i]); }
inline void print_ints(int * y, int n)
{
for(int i = 0; i < n; ++i)
print_int(y, i);
}
template<int n> // C++
inline void print_ints(const int[n] & y) { print_ints(&y[0], n); }
int [] y = { 0, 1, 4 };
print_ints(y); // C++
// or in C:
print_ints(y, sizeof(y)/sizeof(int));
Now, what if you absolutely want the generated code to look like solution 3. ? This means you need the iteration to happen at compile-time. Tricky!
That's where the preprocessor can come into play. There are (hacky) ways to make it do this kind of things. I strongly recommend not implementing this yourself (except to play), but use the Boost.preprocessor library instead:
#define PRINTER(R,D, NUMBER) printf("%d\n", NUMBER);
#define NUMBERS (0, 1, 4)
BOOST_PP_LIST_FOR_EACH(PRINTER, _, BOOST_PP_TUPLE_TO_LIST(NUMBERS))
// will expand to printf("%d\n", 0); printf("%d\n", 1); printf("%d\n", 4);

Under standard C, this is not possible; during preprocessing, the compiler simply sees the identifier i as simply that - an identifier. It does not know that i is of type int, or that it's even a variable in the first place.
The easiest way to achieve what's intended is to use an array, like so:
int i;
int y[] = { 0, 1, 4 };
for (i = 0; i < 3; i++) // NOTE: arrays in C start at index 0, not 1
{
printf("%d \n", y[i]);
}
Also note that I got rid of the macro, as you want to use the value of a runtime variable i to select another runtime variable.

Related

Call #define multiple times based on a specific value

If you call something like this in C:
#include <stdio.h>
#define REPS ,a
...
int a = 1;
printf("%d" REPS);
It will work, but is it possible to call the REPS macro multiple times based on an unknown value, like for example, that I want to have five inputs in a scanf, yet I want my code to automate it (for example, if #define REPS ,a[i] then: ... ,a[1] ,a[2])?
It will work, but is it possible to call the REPS multiple times based in an unknown value
No. #define creates a preprocessor macro that you can use in your code, but when the compiler compiles your code, the actual value is substituted for the macro. If you have:
#define FOO 7
for example, then every occurrence of FOO in your code is replaced by 7 before the code is compiled; by the time the compiler sees your code, there's no #define and no FOO, only 7 wherever FOO was. Although there are some other preprocessor commands (e.g. #if) that can control whether a given #define is evaluated at all, there are no other preprocessor control structures (loops etc.).
I want to have five inputs in a scanf, yet I want my code to automate it (for example, if #define REPS ,a[i] then: ... ,a[1] ,a[2])?
You can certainly automate something like that; it's just that the preprocessor isn't the right tool for the job. Consider:
int reps = 5
//...
for (int i = 0; i < reps; i++) {
scanf(" %d", &a[i]);
}
REPS is evaluated at compile time, so it cannot depend on run-time values in this case a. There are hacks but in general you cannot do compile loops with macros.
I suggest you write a function along these lines instead:
#include <stdio.h>
void print_int_array(size_t n, int a[n]) {
for(int i = 0; i < n; i++)
printf("%d%s", a[i], i + 1 < n ? ", " : "\n");
}
int main() {
print_int_array(0, (int []) {});
print_int_array(1, (int []) {1});
print_int_array(2, (int []) {1, 2});
}

Shake sort using MACRO

Shake sort of vector:
program works, but:
I was trying to use the same function for bubble up and bubble down for shake sort (bubble up to get the MAX value to the right and bubble down to get the min value to the left). In order to do it I was trying to use the following MACRO which does not compile:
sign is '+' and oper is '>' for bubble
sign is '-' and oper is '<' for bubble down
for bubble up -
start is iterator i (iterated the Vector indices)
end is n-1-i;
for bubble down -
swap start and end values
#define bubble_up_down(var_t, pVector, _Is_swp, start, end, sign, oper)\
{\
var_t current_index;\
var_t current_val;\
var_t next_val;\
for (current_index = *(start) ; current_index (oper) *(end) ; (sign)(sign)current_index){\
{\
VectorGet((pVector), current_index, &current_val);\
VectorGet((pVector), current_index(sign)1, &next_val);\
if(current_val (oper) next_val)\
{\
VectorSet((pVector), current_index, next_val);\
VectorSet((pVector), current_index(sign)1, current_val);\
*(_Is_swp) = 1;\
}\
}\
}
Need your advice to fix this macro.
It is not really clear why you want to use a macro here. Do you want to avoid duplicaing code? Or do you want to make your sorting routine type independent?
Anyway, your macro has several errors:
You've probably read that you should guard macro arguments with parentheses. That is usually good advice, because macros are text replacements; for example infamous SQ(x + 1) will resolve to x + 1*x + 1. In your case, the advice is wrong-headed. You will get syntactically wrong "operators" such as (-) and (<) in your code. Just use sign and oper.
Even so, sign sign will resolve to - - or + +, which is not what you want. You could rewrite i++ to the equally valid i = i + 1 or you could use the token-pasting operator, sign##sign, which would produce -- or ++.
Macros aren't functions. You are probably going to invoke your macro inside a function. All local variables that are in scope hen you invoke the macro are also in scope for the macro. That means there is probably no need to define all these pointers.
Why do you pass the array element type, var_t? I reckon that SetVector and GetVector aren't macros, so the type independence falls flat.
If var_t is the type of your array elements, your index isn't necessarily of the same type; it should be an integer type. (Your elements must be comparable with the < operator, so it is one of the arithmetic types, but image what happens if you have an array of char that is longer than 256 elements?)
If your elements are of arithmetic type, there's probably no need for the GetValue and SetValue calls. You can just assign values with the = operator .
All this makes me think that you don't really know what you're doing. That plus the known pitfalls and shortcomings of macros are a good reason not to use any macros here.
Addendum In comments, The PO has said that the macro should achieve two things: It should avoid repeated code and it should make the sorting independent of the types of the array elements. These are two different things.
Writing short local macros to avoid repeating code can be a useful technique, especially, if the code needs to keep variables in sync in several places. Is it useful in your situation?
So you've got your upward-bubbling code:
int done = 0;
while (!done) {
done = 1;
for (int i = 1; i < n; i++) {
if (a[i - 1] > a[i]) {
swap(a, i - 1, i);
done = 0;
}
}
}
(This uses a swap function to swap two array elements. It is more straightforward than your version, because it doesn't use get/set accessor functions.) Now you write the downward-bubbling counterpart:
while (!done) {
done = 1;
for (int i = n - 1; i > 0; i--) {
if (a[i - 1] > a[i]) {
swap(a, i - 1, i);
done = 0;
}
}
}
These two snippets differ only in the loop control. Both visit all indices from 1 to n - 1. So your macro needs to pass the start and end values. But it also needs to know which way the comparison goes – less than or greater than – and whether to increment or to decrement the index. That's four pieces of data for a simple loop.
You could try to get rid of the comparison and use != for both directions. But then your loops will fail if the array is empty.
The above backwards loop will already fail on empty arrays when you use an unsigned integer as index. Forward and backward lops are asymmetric an C, because the lower and upper bounds are asymmetric, too: Lower bound are always inclusive, upper bound are always exclusive. This forward loop:
for (unsigned int i = 0; i < n; i++) ...
Has the following backward equivalent:
for (unsigned int i = n; i-- > 0; ) ...
Here, the decrement occurs in the condition and the update part is empty. The advantage is that it uses exactly the same bounds, 0 and n, verbatim, but by decrementing before entering the loop body, the same valid range of numbers, 0 to n - 1 are visited. And it works with unsigned ints, which are a natural choice for looping variables.
To cut a long story short: Forward and backward loops are asymmetric in C, so it is not easy to write a macro for them. C's for syntax is more verbose than for i = 1 to n, but that's how it is. Embrace it and alleviate the typing pain by chosing appropriate index names: it's i, not current_index.
Can you make the code less redundant without macros? Of course: You can write two functions for bubbling up and down once:
static int bubble_up(int a[], int n)
{
int done = 1;
for (int i = 1; i < n; i++) {
if (a[i - 1] > a[i]) {
swap(a, i - 1, i);
done = 0;
}
}
return done;
}
static int bubble_down(int a[], int n)
{
int done = 1;
for (int i = n; i-- > 1; ) {
if (a[i - 1] > a[i]) {
swap(a, i - 1, i);
done = 0;
}
}
return done;
}
(These functions are static, i.e. private to the current compilation unit.) Now your actual sorting functions look like this:
void sort_bubble_up(int a[], int n)
{
int done = 0;
while (!done) {
done = bubble_down(a, n);
}
}
void sort_bubble_down(int a[], int n)
{
int done = 0;
while (!done) {
done = bubble_down(a, n);
}
}
void sort_shaker(int a[], int n)
{
int done = 0;
while (!done) {
done = bubble_up(a, n) || bubble_down(a, n);
}
}
If you are not afraid of empty loop bodies, you can even get them down to:
void sort_bubble_up(int a[], int n)
{
while (bubble_down(a, n)) { }
}
void sort_bubble_down(int a[], int n)
{
while (bubble_down(a, n)) { }
}
void sort_shaker(int a[], int n)
{
while (bubble_up(a, n) || bubble_down(a, n)) { }
}
All this code works only for int arrays, though. The standard library's way of approaching type independence is to work on the byte level via void * pointers and user-defined comparison functions. The sorting function qsort does this, for example.
C++ and other languages have templates, where you can write an algorithm for several types. When you "instantiate" a template, the compiler creates a function for just this type, which is then called.
You could emulate this with macros. If you just want to call your macro in the function body, you could define:
#define BUBBLE_SORT(ARRAY, N, TYPE) do { \
int done = 0; \
int i; \
\
while (!done) { \
done = 1; \
\
for (i = 1; i < N; i++) { \
if (ARRAY[i - 1] > ARRAY[i]) { \
TYPE sawp = ARRAY[i]; \
\
ARRAY[i] = ARRAY[i - 1]; \
ARRAY[i - 1] = swap; \
done = 0; \
} \
} \
} \
} while (0)
and then use the macro like so:
char c[] = "Mississippi";
BUBBLE_SORT(c, strlen(c), char);
(That do { ... } while (0) thing around thze macro makes the macro behave like a function call, sort of. The new scope of the loop body allows for local variables.)
The problem here is that such multi-line macros are hard to debug. When there is an error in the body, you just get the number of the line where the macro is invoked in an error message. (But you can use -E with most compilers to see how the preprocessor resolves that macro.)
Conclusion:
Macros can be useful, but you have to know what you are doing. In general, try to avoid them, because they are hard to debug and often hard to understand for others. (And this other person might be you half a year later.)
If you must use macros, try to make then look as natural as possible. Passing operators like > or + should make you wary.
Use functions, not macros, for common code.
Embrace C's way to deal with different types. It will be more useful (if less fun) to learn how qsort works than to fiddle with macros for a bubble sort implementation.
If you really need to write a lot of type-independent code, you probably shouldn't use C.

Macro function to behave like for loop

Consider the following code i managed to write:
#include <stdio.h>
#define FOR(A, B, C) for(A; B; C++)
int main()
{
FOR(i=0, i<10, i)
printf("%i", i);
return 1;
}
The output is:
0123456789
If i do FOR(i=5, i<10, i)
then respectively the output is 56789
My questions are is that legal? Will it cause any errors in different cases? Does it works exactly like a for loop?
Yes it's a "legal" macro, but no, it does not work like a real for loop.
Your macro won't handle this:
int a, b;
for(a = 0, b = 4711; a < b; ++a);
for instance, since you can't distinguish the , used to build a longer initializing expression to the one used to separate the expressions that make up the parts:
FOR(a = 0, b = 0, a < b, ++a);
will break, since it looks like a call with 4 arguments instead of 3.
A macro is just copied everywhere the preprocessor sees you using the macro keyword. It just copies the text, nothing more.
To elaborate on that a bit more, consider this example:
#define MY_MACRO a
int MY_MACRO = 5;
When the preprocessor comes along it will take the above and change it to:
int a = 5;
and then the compiler will come along and compile it like normal C/C++ code.
When you add arguments to your macro, they are just substituted in place within your macro. This can be a problem, consider the following two macros:
#define BAD_MACRO(a, b) a*b
#define GOOD_MACRO(a, b) (a)*(b)
They look almost the same, but consider the following:
int k = BAD_MACRO(2, 3); // k = 2*3 = 6
int j = GOOD_MACRO(2, 3); // j = 2*3 = 6
int m = BAD_MACRO(2+1, 3); // m = 2+1*3 = 5
int n = GOOD_MACRO(2+1, 3); // n = (2+1)*3 = 9
Although note that neither of these macros are good or bad, they just don't have the same behaviour as a typical function.

How can i access the value of a ruby array in C? (editing array.c:rb_ary_initialize from ruby source code)

arr=Array.new(3)
arr[0]=5
arr[1]=3
arr[2]=2
These lines should call this function, https://github.com/ruby/ruby/blob/trunk/array.c#L568 according to this, http://www.ruby-doc.org/core-1.9.3/Array.html
So I have added couple of lines there to display the values of array. But i didn't get the expected result.
else {
memfill(RARRAY_PTR(ary), len, val);
ARY_SET_LEN(ary, len);
int i;
int result;
result = 0;
VALUE *s_arr = RARRAY_PTR(ary);
for(i = 0; i < len; i++) {
result = LONG2NUM(s_arr[i]);
printf("r: %d\n",result);
}
}
I got the result like this:
arr=Array.new(3)
arr[0]=5
arr[1]=3
arr[2]=2
r: 9
r: 9
r: 9
Why is this result? Why 9?
I have followed these to solve it:
How to convert ruby array to C array with RubyInline?
https://github.com/ruby/ruby/blob/trunk/README.EXT#L131
https://github.com/ruby/ruby/blob/trunk/include/ruby/ruby.h#L708
https://github.com/ruby/ruby/blob/trunk/include/ruby/ruby.h#L731
Can anyone please help to display/printf the value of Ruby array in C?
This doesn't make any sense:
result = LONG2NUM(s_arr[i]);
LONG2NUM is used to convert a C long int to a Ruby VALUE that holds a number; s_arr[i] is already a VALUE so you're effectively doing things like VALUE v = LONG2NUM((VALUE)5). LONG2NUM is defined in ruby.h as a wrapper for this:
#define LONG2NUM_internal(v) (FIXABLE(v) ? LONG2FIX(v) : rb_int2big(v))
and if v fits in a VALUE without converting it to a bignum, then you end up using this:
#define INT2FIX(i) ((VALUE)(((SIGNED_VALUE)(i))<<1 | FIXNUM_FLAG))
So you're basically doing a bunch of bit wrangling on a pointer and wondering why it always says 9; consider yourself lucky (or unlucky) that it doesn't say segmentation fault.
You want to convert a VALUE which holds a number to a C integer. You probably want to use FIX2LONG:
#define FIX2LONG(x) (long)RSHIFT((SIGNED_VALUE)(x),1)
or NUM2LONG:
#define NUM2LONG_internal(x) ((long)(FIXNUM_P(x) ? FIX2LONG(x) : rb_num2long(x)))
#ifdef __GNUC__
#define NUM2LONG(x) \
__extension__ ({VALUE num2long_x = (x); NUM2LONG_internal(num2long_x);})
#else
static inline long
NUM2LONG(VALUE x)
{
return NUM2LONG_internal(x);
}
#endif
So something like this:
long result;
for(i = 0; i < len; i++) {
result = NUM2LONG(s_arr[i]);
printf("r: %ld\n", result);
}
Note the switch to %ld since we're using longs now and we always turn on all the picky compiler flags that complain about mismatched printf formats and arguments. Of course, this assumes that you are certain that the array contains numbers that will fit in a C long.

Reading variables with C preprocessor

I'm running into the following problem when trying to use concatenation with the C preprocessor:
#define substitute(id) var##id
int main()
{
int var0 = 999;
int var1 = 998;
int var2 = 997;
int var3 = 996;
int var4 = 995;
int i = 0;
for(i; i < 5; i++)
{
printf("Valor: %i \n", substitute(i));
}
system("PAUSE");
return 0;
}
Is there a way for the preprocessor to be able to read the value on "i" instead of just concatenating "vari"?
No. The preprocessor works before compilation and therefore before execution.
The define
#define substitute(id) var##id
will cause your loop to expand to:
for(i; i < 5; i++)
{
printf("Valor: %i \n", vari);
}
The preprocessor has no knowledge of the variable i, nor should it.
You should probably use an array:
int var[5] = {999,998,997,996,995};
and access it via []:
for(i; i < 5; i++)
{
printf("Valor: %i \n", var[i]);
}
That's not possible at the pre-processor stage because what you want depends on values that are only known later, at runtime.
What you need is an array and the index operator, var[i].
You need to be aware that the macro is resolved once (by the preprocessor) before the file is compiled, so at runtime, each iteration in the loop will render the same result when "calling" substitute.
Nope, because the preprocessor runs at compile time, not runtime, but you can use an array:
int vars[] = { 999, 998, 997, 996, 995 };
for (int i = 0; i < 5; ++i)
printf("Valor: %i \n", vars[i]);
No i is a runtime evaluation. There is no way for the preprocessor to know what the value of I could be.
Why would you do this with the preprocessor?
You seem to be trying to reinvent arrays:
int main() {
int var[] = {999, 998, 997, 996, 995};
int i;
for (i=0; i<5; i++)
printf("Valor: %i\n", var[i]);
return 0;
}
As many said - no, macros doesn't know anything about what's going on in program compile-time or run-time. But... if you wish you can generate some hackish code with macro which operates with stack directly (do not try this in home alone - it can blow your computer apart !! :-) )- define your macro as:
#define substitute(adr, max, id) *(adr + max - id)
and call like this:
printf("Valor: %i \n", substitute(&var4,4,i));
But keep in mind that this is just for curiosity, in real life it is not recommended to play directly with stack, because compiler may (and usually will) re-order variable allocation on stack and also you will risk some nasty bugs to happen and etc... So better as others said - make some array and operate on that.
hth!
C macros are only expanded at compile time and your printf line would become
printf("Valor: %i \n", vari);

Resources