Macro vs Function

C/C++ code snippet 1 (macro):

1
#define ARR_LEN_BY_MACRO(x) sizeof(x)/sizeof(*x)

C/C++ code snippet 2 (function):

1
2
3
4
int ARR_LEN_BY_FUNC(int *x)
    {
     return sizeof(x)/sizeof(*x);
    }

An integer array of 5 elements is declared and initialized in main() as int arr[5]={1,2,3,4,5}; .

The macro and function of the code snippets above are declared and defined globally.

From main() , the macro and the function are called with the argument arr as follows,

1
2
m=ARR_LEN_BY_MACRO(arr);
f=ARR_LEN_BY_FUNC(arr);

What's the absolute difference between the values stored in m and f , i.e., what's the value of m f |m-f| ?

Details and Assumptions:

  • m and f are int variables.

  • sizeof() is an inbuilt C/C++ function which returns the number of bytes occupied by an object.

  • main() is the function block which is called first when the code is compiled and executed.

  • Assume that the code is being executed in a 32-bit compiler on a 32-bit machine, which means that an int or int* variable takes 4 bytes of memory, i.e., we have sizeof(int) = sizeof(int*) =4.

0 Trick question, the code doesn't even run 2 3 5 1 4

This section requires Javascript.
You are seeing this because something didn't load right. We suggest you, (a) try refreshing the page, (b) enabling javascript if it is disabled on your browser and, finally, (c) loading the non-javascript version of this page . We're sorry about the hassle.

1 solution

Just Run It! ( Solution )

Explanation(in brief):

The Macro snippet always return the number of indecies of an array so m= 5 \boxed{5} according to the problem.

The Function snippet always return 1 since: return sizeof(x)/sizeof(*x); so f= 1 \boxed{1}

m f = 4 \huge |m-f| = \huge 4

Your solution doesn't seem to explain anything.

The real question is "Why does the function snippet and the macro return different results when both have the same definition (i.e., to compute sizeof(x)/sizeof(*x) )?"

To help you write up a complete solution, here's a hint:

Hint: Are you familiar with array decaying ?

Prasun Biswas - 5 years, 1 month ago

Log in to reply

Now, I know that array decaying, but I don't understand 'something' that make the sizeof() operator no longer give the size of an array, can you explain? I'm just guessing sizeof(x)/sizeof(*x) is 'something' that cause array decaying

Resha Dwika Hefni Al-Fahsi - 5 years, 1 month ago

Log in to reply

That "something" which causes array decay is the type conversion of the array's base address to an int pointer (i.e., int* ) when it's passed to the function as a parameter. An array decay makes the sizeof() function not work as expected because a simple int* doesn't retain the size of the int array it points to. When you're using sizeof() inside the function, you're no longer computing the size of the array and then dividing it by the size of an element of the array. You're simply computing sizeof(int*)/sizeof(int) which is 4 4 = 1 \frac 44=1

Prasun Biswas - 5 years, 1 month ago

Log in to reply

@Prasun Biswas sizeof(int*)/sizeof(int) inside the macro mean the size of array and sizeof(int*)/sizeof(int) inside the function no longer computing the size of an array but dividing it? So, if we want to know the size of the array inside the function we simply write return sizeof(int*) or return sizeof(int) ?

Resha Dwika Hefni Al-Fahsi - 5 years, 1 month ago

Log in to reply

@Resha Dwika Hefni Al-Fahsi You can't. There's no way to compute the size of an arbitrary array inside a function that typecasts array base address pointer into a simple int* and then works with it. This is because when the array base address pointer is typecasted to int* as it is passed through the function, the pointer becomes just a pointer to the starting element of the array and loses information about length of the entire array since a pointer pointing to just a single element cannot have information about other elements. We can however traverse through the array using this typecasted pointer since arrays are contiguous blocks of memory and so we only need to increment the pointer to one element to go to the next element.

Prasun Biswas - 5 years ago

0 pending reports

×

Problem Loading...

Note Loading...

Set Loading...