3

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;
}
MahD
  • 77
  • 9

1 Answers1

5

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.

Clifford
  • 88,407
  • 13
  • 85
  • 165