I was working with C++ for a long time and now I am on a C project.
I am in the process of converting a C++ program to C.
I am having difficulty with the constants used in the program.
In the C++ code we have constants defined like
static const int X = 5 + 3;
static const int Y = (X + 10) * 5
static const int Z = ((Y + 8) + 0xfff) & ~0xfff
In C, these definitions throw error.
When I use #defines instead of the constants like
#define X (5+3);
#define Y (((X) + 10) * 5)
#define Z ((((Y) + 8) + 0xfff) & ~0xfff)
the C compiler complains about the definitions of "Y" and "Z".
Could anyone please help me to find a solution for this.
You need to remove the semi-colon from the #define X line
#define X (5+3)
#define Y (((X) + 10) * 5)
#define Z ((((Y) + 8) + 0xfff) & ~0xfff)
#define X (5+3); is wrong, it needs to be #define X (5+3) (without ';')
also be aware of the difference between using static const and #define: in static const, the value is actually evaluated, in #define, it's pre-processor command, so
#define n very_heavy_calc()
...
n*n;
will result in evaluating very_heavy_calc() twice
Another option is to use an enum:
enum {
X = 5 + 3,
Y = (X + 10) * 5,
Z = ((Y + 8) + 0xfff) & ~0xfff
};
Related
I got the following code:
p = B[m] & B[m + 5] & B[m + 6] & B[m + 11];
m -= d * (l > 0) * 11 + !d * (c % 5 > 0);
p += m ^ M ? B[m] & B[m + 5] & B[m + 6] & B[m + 11] : 0;
I know it's hard to read, but here's a TL;DR for it : I check multiple bits (all are related to m) in a bitset, then i change the value of variable m and i check again (other bits). Is there a way i can acces those bits in less code, or to template the check (cuz are the same formulas for bits)?
B[m] & B[m + 5] & B[m + 6] & B[m + 11]
Thank you :D.
I suggest using a function to precompute a helper bitset for that:
bitset<99> prepare_bitset(const bitset<99>& B)
{
return B & (B<<5) & (B<<6) & (B<<11);
}
Then you can just use it like this:
auto HB = prepare_bitset(B);
p = HB[m];
m -= d * (l > 0) * 11 + !d * (c % 5 > 0);
p += m ^ M ? HB[m] : 0;
UPD: Another option is to just define HB in place:
auto HB = B & (B<<5) & (B<<6) & (B<<11);
p = HB[m];
m -= d * (l > 0) * 11 + !d * (c % 5 > 0);
p += m ^ M ? HB[m] : 0;
Make a function that takes B and m.
So p = yourFunc(B, m) and p += m ^M ? yourFunc(B, m) : 0
The function is something like:
TYPEOFP yourFunc(TYPEOFB b, TYPEOFM m) {
return b[m] & b[m + 5] & b[m + 6] & b[m + 11];
}
I don't know your types, so you need to fill it in.
I wouldn't recommend a macro, but if you want that it's
#define yourMACRO(b, m) ((b)[(m)] & (b)[(m) + 5] & (b)[(m) + 6] & (b)[(m) + 11])
All of those extra parens are to protect you if you ever pass in an expression for b or m. The macro will fail if you pass in something with side-effects (like ++m).
EDIT: From your comments, you said you can't write outside the function.
It's unorthodox, but you can do the #define in the function and #undef it at the end of the function.
Depending on the version of C++ you have, you might have lambdas, which let you make function expressions.
If you are desperate, you can define an inner class or struct with a static function: C++ can we have functions inside functions?
This question already has answers here:
The need for parentheses in macros in C [duplicate]
(8 answers)
Closed 7 years ago.
Suppose we have this expression:
#define cube(x) x * x * x
And then we call it:
int n = 3, v;
v = cube(n + 1); // v = 10
v = cube((n + 1)); // v = 64
v = cube(n); // v = 27
So the question is: why first operation do not make v = 64?
Macros are not evaluated (in the sense of the common interpretation of evaluation), they are expanded at compile time.
Before the file is compiled, there is another program called the C Preprocessor that replaces the macro invocation literally/textually and prepares the file for actual compilation, so for your macro
#define cube(x) x * x * x when you do this
This
v = cube(n + 1);
is replaced with this (expaned is the correct term)
v = n + 1 * n + 1 * n + 1;
// Simplifies to
v = n + n + n + 1;
// and again
v = 3 * n + 1;
which for n = 3 gives you 10 exactly the observed result.
Note, that when you add parentheses
v = cube((n + 1));
then, the expansion is
v = (n + 1) * (n + 1) * (n + 1);
which is what you would expect cube() to do, so prevent this you should redefine your macro like this
#define cube(x) ((x) * (x) * (x))
If you are using gcc try
gcc -E source.c
and check the result to verify how the macro was expanded.
I was trying to write a simple CUDA function to blur images. I use myself defined max and min macro as
#define min(a, b) ((float)a > (float)b)? (float)b: (float)a
#define max(a, b) ((float)a > (float)b)? (float)a: (float)b
The part of __global__ kernel is:
float norm;
float sum = 0;// when filter exceed border, norm will affect!
int center = radius * filterWidth + radius;
int imgx = 0, imgy = 0;
for (int y = -radius; y <= radius; y++)
{
for (int x = -radius; x <= radius; x++)
{
imgx = min(max(x + absolute_image_position_x, 0), numCols-1);
//imgx = min(numCols - 1, imgx);
imgy = min(max(y + absolute_image_position_y, 0), numRows -1);
//imgy = min(numRows-1, imgy);
sum += (float) inputChannel[(imgy*numCols) + imgx] * filter[center + (y*filterWidth) + x];
}
}
outputChannel[pos] = (unsigned char) sum;
But the min and max can not give correct answer when I tried to debug. For example, min(max(10,0),100) will give 100.0f!
I did not check each step why it was wrong. But later I changed to cuda math functions, the results became right.
Anyone has idea. Is there any restriction in use of macro in CUDA kernel?
Getting rid of the (float) to clear the clutter, your macros look like this:
#define min(a, b) (a > b)? b: a
#define max(a, b) (a > b)? a: b
And example use (simplifying a few variable names):
imgx = min(max(x + aipx, 0), nc-1);
will expand to:
imgx = ((x + aipx > 0)? x + aipx: 0 > nc-1)? nc-1: (x + aipx > 0)? x + aipx: 0;
Perhaps that is getting parsed incorrectly? Try putting extra parens around the use of your macros' arguments:
#define min(a, b) ((a) > (b))? (b): (a)
#define max(a, b) ((a) > (b))? (a): (b)
I have this simple code that converts between degrees Farehnheit and degrees Celcius. I defined some macros to do it, but I'm getting some weird results when I use it. I use this method when absoluteTemp = 373.15 (the boiling point of water in kelvin).
#define kelvinToCelc(k) k - 273.15
#define celcToFahren(c) (9.0 / 5.0) * c + 32
double x = kelvinToCelc(absoluteTemp); // 100
double y = celcToFahren(x); // 212
double z = celcToFahren(kelvinToCelc(absoluteTemp)); // 430.52???
return celcToFaren(kelvinToCelc(absoluteTemp));
After expanding macro in
double z = celcToFahren(kelvinToCelc(absoluteTemp));
It becomes
double z = (9.0 / 5.0) * absoluteTemp - 273.15 + 32
You need to add parentheses to the macros
#define kelvinToCelc(k) (k - 273.15)
#define celcToFahren(c) ((9.0 / 5.0) * c + 32)
The old rule was : Use more parenthesis in macros around everything:
#define kelvinToCelc(k) ((k) - 273.15)
#define celcToFahren(c) ((9.0 / 5.0) * (c) + 32)
Notice parens around the whole macro and all macro arguments
The new rule is : Use inline functions They have typechecking, evaluate arguments only once, and because they don't need so many parenthesis *
Note: * Some exceptions may apply, this is not one of them
This is what that looks like as inline functions
inline double kelvinToCelc(double k)
{
return k - 273.15;
}
inline double kelvinToCelc(double c)
{
return (9.0 / 5.0) * c + 32;
}
Notice that you have to put inline and the return type before the name, add types to all arguments, and add a ; at the end
Notice how you can use newlines to make it easier to read, and also so you can step into it in the debugger
Macros are simple - Just a text replacement
i.e.
double z = celcToFahren(kelvinToCelc(absoluteTemp));
becomes
double z = (9.0 / 5.0) * kelvinToCelc(absoluteTemp) + 32
Then becomes
double z = (9.0 / 5.0) * absoluteTemp - 273.15 + 32
Now just do the maths
i.e.
double z = (9.0 / 5.0) * 373.15 - 273.15 + 32;
If you are going to use macros, make your life easier with parenthesis
#define kelvinToCelc(k) (k) - 273.15
#define celcToFahren(c) (9.0 / 5.0) * (c) + 32
This helps prevent the unexpected results you are seeing. The reasons have already been pointed out in other posts
Just one thing i should add to the other answers, try running just the preprocessor and look at the output ie:
g++ -E -P main.cpp
The answer 431.52 is correct. It expanded like this
(9.0/5.0) * 373.15 - 272.15 + 32
In mathematics [* and /] take precedence over [+ and -]. So the equation expanded like
((9.0/5.0) * 373.15) - 272.15 + 32
(671.67) - 272.15 + 32
399.52 + 32
431.52
[* and /] have same precedence so there order doesn't matter and similarly [+ and -] have same precedence so their execution order doesn't matter.
For macros, it just relies on textual substitution. So it is equivalent to:
double z = (9.0 / 5.0) * absoluteTemp - 273.15 + 32;
That's why you got wrong result.
Edit:
Try to use (inline) functions instead even you can make it work by adding more parenthesis: (see #2)
#define celcToFahren(c) ((9.0 / 5.0) * (c) + 32)
Macros are also error-prone because they rely on textual substitution and do not perform type-checking. Check out here for more info.
I have a problem with this piece of C code:
int y = 0, h = 640, ih = 640;
h = y + h - max(0, (y + h) - ih);
It should set h to 640, but instead it is setted to 0!
You can see it running here: http://ideone.com/zBZSsr
Any idea about this strange behavior? Am I doing something wrong?
The max macro in the example you linked needs an extra pair of parentheses.
You have:
#define max(x, y) ((x) > (y)) ? (x) : (y)
In your example, this expands to:
h = y + h - ((0) > ((y+h)-ih)) ? (0) : ((y+h)-ih);
I believe the operator precedence means that everything on the left is subsumed into the condition expression for the ternary operator. There's some implicit conversion from bool to int and back again, resulting in an always-true condition, so you then get the true branch, which is simply 0.
Your macro should be:
#define max(x, y) (((x) > (y)) ? (x) : (y))
your code gets preprocessed to
h = y + h - ((0) > ((y + h) - ih)) ? (0) : ((y + h) - ih);
the problem is that + and - has priority over ?: operator.
#define max(x, y) ((x) > ((y)) ? (x) : (y))
add () around the defines and your computation will be correct.