This question already has answers here:
C Programming Macros multiplication [duplicate]
(2 answers)
Closed 4 years ago.
I used the #define command for following code and constants. I defined in the first WORKLOAD_MAX with 4 and second line TASK_COUNT_MAX with 10 and used multiplication of them in the third line.
after a long time debugging, I realized that the correct value does not apply while executing the code, and I have to manually set the value that I do not like it. (like 40 on the fourth commented line)
Someone can help.
Thank you
#define WORKLOAD_MAX 4
#define TASK_COUNT_MAX 10
#define READY_LOOP_DEEP TASK_COUNT_MAX*WORKLOAD_MAX
//#define READY_LOOP_DEEP 40
struct workItem // It is a STRUCT to keep the status of task in different stages
{
int task_ID; // Task ID
int workload_ID; // Workload ID
};
// Read from the beginning of the readyQueue
struct workItem readFromReadyQueue()
{
struct workItem witem;
// Picking up from queue head
witem = readyQueue[readyQueueHead];
// Move forward the queue head index in rotation
readyQueueHead = (readyQueueHead + 1) % READY_LOOP_DEEP;
// Reduce the number of queue elements
readyQueueSize--;
#ifdef PRINT_ReadReadyQueue
printf("Task_ID #%d (Workload_ID #%d) read from readyQueue.\n", witem.task_ID , witem.workload_ID);
#endif
return witem;
}
Macros are textual replacements the semantics of which are context dependent. In this case any occurrence of READY_LOOP_DEEP will be replaced with 4*10 which in context may not behave as you might expect due to operator precedence and evaluation order. It is an example of a dangerous macro, and should be written thus:
#define READY_LOOP_DEEP (TASK_COUNT_MAX * WORKLOAD_MAX)
with parentheses to ensure the evaluation order is as expected.
In your case the expression:
readyQueueHead = (readyQueueHead + 1) % READY_LOOP_DEEP;
expands to:
readyQueueHead = (readyQueueHead + 1) % 4 * 10 ;
with left-to-right evaluation, so (readyQueueHead + 1) % 4 is multiplied by 10, rather than (readyQueueHead + 1) % 40 as you intended.
The parentheses change the expression to:
readyQueueHead = (readyQueueHead + 1) % (4 * 10) ;
which will evaluate as you intended.
Related
I don't understand how #define LEFT (phnum + 4) % N is allowed as phnum is not even defined.
#define N 5
#define LEFT (phnum + 4) % N
#define RIGHT (phnum + 1) % N
int state[N];
int phil[N] = { 0, 1, 2, 3, 4 };
sem_t mutex;
sem_t S[N];
void test(int phnum)
{
if (state[phnum] == HUNGRY
&& state[LEFT] != EATING
&& state[RIGHT] != EATING) {
// state that eating
state[phnum] = EATING;
sleep(2);
}
The statement #define LEFT (phnum + 4) % N defines a “macro” named LEFT whose replacement list is (phnum + 4) % N. The compiler does not need to know anything about the names in the replacement list; it simply remembers it.
When LEFT is seen later in the source code, the compiler replaces it with the replacement list, (phnum + 4) % N. Thus state[LEFT] != EATING becomes state[(phnum + 4) % N] != EATING.
After that replacement, the compiler interprets the names according to the declarations it has seen for them.
Conceptually, all of the “preprocessor” operations, such as defining macros, replacing them with their replacement lists, and processing #if and other statements marked with #, occur before the semantic analysis of the program. It is called “preprocessing” because historically it was done in a separate processing stage before compilation, even with a separate program. In modern compilers, the preprocessor operations may be interleaved with the rest of compilation, but the results are the same.
#define LEFT (phnum + 4) % N defines a macro. Macro replacement is performed by the pre-processor before the compiler actually compiles your code. In other words state[LEFT] gets replaced by state[(phnum + 4) % N] before the compiler processes your code.
In case you're using GCC: Passing the -E parameter tells GCC to stop after the pre-processing stage so you can inspect the output. Note that the pre-processor also takes care of #include lines so you might need to search for the interesting part in the output.
This question already has answers here:
Compiler warning - suggest parentheses around assignment used as truth value
(3 answers)
Closed 5 years ago.
While looking into a piece of code, I saw this line:
if ((b = a)) { /* statements */ }
Reading the context, I know its intention is like this:
b = a;
if (b != 0) { /* statements */ }
I know the two lines above can be simplified into the first code block, but why are the two pair of parentheses? Wouldn't that seem redundant? I think this is totally OK:
if (b = a) { /* statements */ }
Usually one do that to avoid the warning from the compiler, that the assignment is to be (then) evaluated as a condition (in case the developer missed an = in ==)
warning: suggest parentheses around assignment used as truth value
Something more indicative,
int c = !!(b = a); // condition
if (!!(b = a)) {
This question already has answers here:
Printing 1 to 1000 without loop or conditionals
(106 answers)
Closed 8 years ago.
i see the question on a c++ programming context, i check for a solution and one of my friend give me this code its works perfect but i can't understand it's logic and also how it's works. i asked to him about it but he also don't know how the program is actually works, i think he is also take this solution from somewhere. Anybody can explain the logic behind this i mean in the line
(&main + (&exit - &main)*(j/1000))(j+1); ?
#include <stdio.h>
#include <stdlib.h>
void main(int j) {
printf("%d\n", j);
(&main + (&exit - &main)*(j/1000))(j+1);
}
Thanks in advance
It works as follows:
Performs the int division j/1000, which will return 0 always while j is smaller than 1000.
So the pointer operation is as follows:
&main + 0 = &main, for j < 1000.
Then it calls the resulting function pointed by the pointer operations passing as parameter j+1.
While j is less than 1000, it will call main recursively with parameter one more than the step before.
When the value of j reaches 1000, then the integer division j/1000 equals to 1, and the pointer operation results in the following:
&main + &exit - &main = &exit.
It then calls the exit function, which finishes the program execution.
I go with the explanation already given but it would be easier to understand if written as below:
void main(int j) {
if(j == 1001)
return;
else
{
printf("%d\n", j);
main(j+1);
}
}
The above code does the same as already written code.
#include<stdio.h>
#include<stdlib.h>
#define d 10+10
int main()
{
printf("%d",d*d);
return 0;
}
I am new to the concept of macros.I found the output for the above program to be 120.What is the logic behind it?
Thanks.
10+10*10+10 == 10 + 100 + 10
Is that clear?
Macros are replaced literally. Think of search/replace. The compiler sees your code as 10+10*10+10.
It is common practice to enclose macro replacement texts in parentheses for that reason:
#define d (10 + 10)
This is even more important when your macro is a function-like macro:
#define SQ(x) ((x) * (x))
Think of SQ(a + b)...
d*d expands into 10+10*10+10. Multiplication comes before addition, so 10 + 100 + 10 = 120.
In general, #define expressions should always be parenthesized: #define d (10+10)
A macro is a nothing more than a simple text replacement, so your line:
printf("%d",d*d);
becomes
printf("%d",10+10*10+10);
You could use a const variable for more reliable behaviour:
const int d = 10+10;
The macro is expanded as is.
Your program becomes
/* declarations and definitions from headers */
int main()
{
printf("%d",10+10*10+10);
return 0;
}
and the calculation is interpreted as
10 + (10 * 10) + 10
Always use parenthesis around macros (and their arguments when you have them)
#define d (10 + 10)
#define
preprocessor directive substitute the first element with the second element.
Just like a "find and replace"
I'm not sure about #include but in C# #define is used at the top to define a symbol. This allows the coder to do things like
#define DEBUG
string connStr = "myProductionDatabase";
#if DEBUG
connStr = "myTestDatabase"
#edif
10+10*10+10 = 20 + 100 = 120
Simple math ;)
Macro doesn't evaluate the value (it doesn't add 10 + 10) but simply replaces all it's occurences with the specified expression.
I have this been given C code where the heading statement includes the following:
#define, EQ(a, b) ((a) == (b))
What does it mean?
The comma is an error that will prevent the code from compiling: I'll assume that it's a typo.
Given:
#define EQ(a, b) ((a) == (b))
This defines a macro for the equality operator ==.
Using this macro later in the code, you can type, e.g.:
if (EQ(2+2, 4))
instead of:
if (2+2 == 4)
Not very useful, really.
It means nothing: this code is ill-formed. The token immediately following a #define must be an identifier, which , is not.
If the , were to be removed, this would define a function-like macro named EQ that takes two arguments.
Let's take it step by step
#define MAX 10
This will replace every instance of the word "MAX" by 10 in your code file. this is very much like defining a constant variable with one major difference. The interpretation of #define statement is done way before compilation. which helps for an example to use MAX as an array size. Which would have caused a compiler error in many cases if you have used a variable instead.
you can use cpp <filename.c> command in Linux terminal to see what will happen when a macro is executed.
for an example this code:
#define MAX 10
int numbers[MAX];
after preprocessing (i.e. interpretation of the preprocessor macros)
int numbers[10];
note that the #define statement will vanish once interpreted.
This takes us to another example
#define square(x) (x * x)
every instance of square(x) in our code will not only be replaced by (x * x) but also the value of x will be replaced. Which has an effect similar to function deceleration but again it is different
so
square(5) will be replaced by (5 * 5)
Finally our example
#define, EQ(a, b) ((a) == (b))
This will replace every instance of EQ(a, b) by ((a) == (b))
so for an example
EQ(4, 5) will be replaced by ((4) == (5))
Now what does "==" mean? it is the "check if equal" if 4 and 5 are equal the whole expression would evaluate as 1 (which obviously is not true) and thus this expression will end up to be evaluated as 0.
Which more or less like the effect of this function
int EQ(int a, int b)
{
return (a == b);
}
Which could be also written as
int EQ(int a, int b)
{
if (a ==b) return 1;
if (a !=b) return 0;
}
Note that with the macro we avoided two variable declarations and there is no function call really and it is in general quicker. This advantage will be obvious if you have a slower processor (or microprocessor).
Finally let me state the obvious
#define simple_macro 5
int some_integer_variable = 10;
.
.
.
some_integer_variable = simple_macro;
simple_macro = 12; /* illegal statement */
simple_macro++; /* illegal statement */
because after running the preprocessor this will be
int some_integer_variable = 10;
.
.
.
some_integer_variable = 5;
5 = 12;
5 ++;
Oh! I might have talked too much but let me leave you with this (obvious) code
#define MAX 10
int variable = MAX; /*this is a MAX variable */
char some_string[] = "the MAX value"; /* no replacement will happen here */
int variable_MAX; /* no replacement will happen here */
after running the preprocessor will be
int variable = 10;
char some_string[] = "the MAX value";
int variable_MAX;