void pointer array parameter passing - arrays

i am trying to pass an int array as argument of a function who receives a void * array
The function is:
void foo(void *A[], unsigned int array_length)
{
for (unsigned int i = 0; i < array_length; i++) {
printf("%d ", (u32)(long)A[i]);
}
}
Then i call like this:
int A[5] = {11, 12, 13, 14, 11};
foo((void *)A, 5);
but the printed array is: 11 13 11 -2015754187 -274447056 and i dont understand why this numbers are printed.

Reading between the lines, Question 4.13: What's the total generic pointer type? in the C FAQ seems tangentially related:
There is no "total generic pointer type.".
The declaration void *A[] indicates that the function is expecting a list of void pointers, not a generic pointer to data elements. The kind of interface you seem to be seeking to implement can be found in the standard qsort function.
void qsort(void *base, size_t nel, size_t width,
int (*compar)(const void *, const void *));
Note base points to the first element of the array to be sorted. Note also that the second and third arguments are essential for qsort to be able to to different elements of the array when invoking the comparison function compar. We assume compar knows what data type its arguments are supposed to be pointing to.
I recommend studying both the prototype of qsort and compar so that you can better frame the design you are after.
While the example below probably does not correspond directly to what you are trying to do, it should be decent starting point for brainstorming:
#include <stdio.h>
#include <stdlib.h>
enum item_type {
INTARR,
INTARRLIST,
DOUBLEARR,
DOUBLEARRLIST,
};
struct item;
struct item {
enum item_type type;
size_t nelem;
void *item;
};
void
print_int_arr(const int *x, size_t nelem)
{
for (size_t i = 0; i < nelem; ++i)
{
printf("%d\n", x[i]);
}
}
void
print_int_arr_list(const struct item *x[], size_t nelem)
{
for (size_t i = 0; i < nelem; ++i)
{
const struct item *y = x[i];
print_int_arr(y->item, y->nelem);
}
}
void
print_item(struct item *x)
{
switch(x->type)
{
case INTARR:
print_int_arr(x->item, x->nelem);
break;
case INTARRLIST:
print_int_arr_list(x->item, x->nelem);
break;
default:
fprintf(stderr, "Unknown item type '%d'\n", x->type);
exit(EXIT_FAILURE);
}
}
int
main(void)
{
int x[] = {1, 3, 5, 7, 9};
struct item a = { INTARR, 5, x };
struct item b = { INTARR, 3, x };
struct item c = { INTARR, 1, x };
struct item *d[] = { &a, &b, &c };
struct item e = { INTARRLIST, 3, d };
print_item(&a);
print_item(&e);
return EXIT_SUCCESS;
}

Actually i need to be able to receive an array of any type because my intention is not to print them but to enqueue them in a queue.
What your foo function lacking is determining the type of data that should be passed as an argument, without it we cannot extract values properly from void*
Below is one of the ways to achieve what you are asking. Here I am passing the type of data and manipulating.
NOTE: This is not a generic function, it is just made to to handle some known types.
you can add more types (pointers and structs etc.) and experiment.
I am printing the data just to be sure we are extracting what we passed, but you can use them as per your need.
#include <stdio.h>
typedef enum { CHAR = 0, INT, FLOAT, STRING} DataType;
const char* getType(DataType t)
{
if(t == CHAR)
return "CHAR";
else if(t == INT)
return "INT";
else if(t == FLOAT)
return "FLOAT";
else
return "STRING";
}
void foo(void *A, unsigned int array_length, DataType type )
{
printf("type is %s and len = %d\n", getType(type), array_length);
switch(type)
{
case CHAR:
{
char *list = (char *) A;
for (unsigned int i = 0; i < array_length; i++) {
printf("%c ", list[i]);
}
}
break;
case INT:
{
int *list = (int *) A;
for (unsigned int i = 0; i < array_length; i++) {
printf("%d ", list[i]);
}
}
break;
case FLOAT:
{
float *list = (float *) A;
for (unsigned int i = 0; i < array_length; i++) {
printf("%.2f ", list[i]);
}
}
break;
case STRING:
{
char**list = (char**) A;
for (unsigned int i = 0; i < array_length; i++) {
printf("%s ", list[i]);
}
}
break;
default:
printf("Invalid type");
break;
}
putchar('\n');
}
int main()
{
int arr_int[] = {11, 12, 13, 14, 11};
//char arr_char[] = {"abcde"}; better way we have '\0' at the end
char arr_char[] = {'a','b','c','d','e'};
float arr_float[] = {11.20, 12.25, 13.70, 14.80, 11.15};
char* arr_strings[] = {"abc","def","ghi","jkl","mno"};
foo(arr_int, sizeof(arr_int) / sizeof(arr_int[0]), INT);
foo(arr_char, sizeof(arr_char) / sizeof(arr_char[0]), CHAR);
foo(arr_float, sizeof(arr_float) / sizeof(arr_float[0]), FLOAT);
foo(arr_strings, sizeof(arr_strings) / sizeof(arr_strings[0]), STRING);
return 0;
}

I think for foo you want an array of integers and not an array of void pointers.
Instead try?
void foo(int A[], unsigned int array_length)
{
for (unsigned int i = 0; i < array_length; i++) {
printf("%d ", A[i]);
}
}
Or if you can't change foo's signature.
void foo(void *A[], unsigned int array_length)
{
int* p = (int*) A;
for (unsigned int i = 0; i < array_length; ++i) {
// printf("%d ", *p++);
printf("%d ", p[i]);
}
}

Related

Generic minimum function using function pointers in C

I am trying to write a generic C function, that returns minimum of an array using function pointers.
The code is :
#include <stdio.h>
int min_index(void *arr, int size, int (*compare)(void *, void *))
{
int i;
int min = 0;
for (i = 1; i < size; i++)
{
if (((*compare)(&arr[i], &arr[min])) < 0)
min = i;
}
return min;
}
int comp_int(int *arr1, int *arr2)
{
if (*arr1 < *arr2)
return -1;
else
return 1;
}
int comp_char(char *arr1, char *arr2)
{
if (*arr1 < *arr2)
return -1;
else
return 1;
}
int main()
{
int arr1[5] = {45, 56, 34, 23, 19};
int index = min_index(arr1, 5, comp_int); // calling min_index with integer array
printf("Minimum value in the array is %d\n", arr1[index]);
char arr2[5] = {'a', 'b', 'c', 'd', 'e'};
int index2 = min_index(arr2, 5, comp_char); // calling min_index with char array
printf("Minimum value in the array is %c\n", arr2[index2]);
return 0;
}
This code worked for only char arrays. It did not work for int arrays.
I debugged the code. I found that, when I call min_index function with the integer array, only first value of arr is correct number, but remaining are some garbage values.
But, when I call min_index function with character array, all the values are correct. There are no garbage values in this case. I got correct output.
Question : Why does the code work for char arrays not for int arrays ?
It doesn't work because you need to cast the array itself on the original type and then access by index. Because C does not have template or a type check you will need to access the min_of() like functions by the size and the sign to get the correct conversion and sorting.
#include <stdio.h>
#define INVALID_VAL_TYPE (int)(~0)
int new_umin_index(void * arr, int arr_len, int vsize){
int i, index = 0;
switch (vsize) {
case sizeof(unsigned char):
for (i = 0; i < arr_len; i++) {
if ( ((unsigned char *)arr)[i] < ((unsigned char *)arr)[index] ){
index = i;
}
}
break;
case sizeof(unsigned):
for (i = 0; i < arr_len; i++) {
if ( ((unsigned *)arr)[i] < ((unsigned *)arr)[index] ){
index = i;
}
}
break;
default:
index = INVALID_VAL_TYPE;
break;
}
return index;
}
int new_imin_index(void * arr, int arr_len, int vsize){
int i, index = 0;
switch (vsize) {
case sizeof(signed char):
for (i = 0; i < arr_len; i++) {
if ( ((signed char *)arr)[i] < ((signed char *)arr)[index] ){
index = i;
}
}
break;
case sizeof(int):
for (i = 0; i < arr_len; i++) {
if ( ((int *)arr)[i] < ((int *)arr)[index] ){
index = i;
}
}
break;
default:
index = INVALID_VAL_TYPE;
break;
}
return index;
}
int main(void) {
int arr1[5] = {45, 56, 34, 23, 19};
int i_min_index = new_imin_index(&arr1, 5, sizeof(int));
printf("Minimum value in array<int> is %i \n", arr1[i_min_index]);
char arr2[5] = {'b', 'a', 'c', 'd', 'e'};
int c_min_index = new_umin_index(&arr2, 5, sizeof(char));
printf("Minimum value in array<char> is %c \n", arr2[c_min_index]);
return 0;
}
I came up with a solution, based on the comments of several users. This time I enabled all the warnings, and took care of every warning. The code is :
#include <stdio.h>
void* minimum(void *arr, int arr_count, size_t size, int (*compare)(const void *, const void *))
{
void* pmin = arr;
for(int i=1; i<arr_count; i++)
{
void* value = (char*)arr + i*size; // size is the sizeof the type.
if(((*compare)(value, pmin))<0)
pmin = value;
}
return pmin;
}
int compare_ints(const void* a, const void* b)
{
int arg1 = *(const int*)a;
int arg2 = *(const int*)b;
if (arg1 < arg2) return -1;
if (arg1 > arg2) return 1;
return 0;
}
int compare_chars(const void* a, const void* b)
{
char arg1 = *(const char*)a;
char arg2 = *(const char*)b;
if (arg1 < arg2) return -1;
if (arg1 > arg2) return 1;
return 0;
}
int main()
{
int arr1[5] = {45, 56, 34, 23, 19};
int *pmin = minimum(arr1, 5,4, compare_ints); // In my system sizeof(int) is 4
printf("Minimum value in the array is %d\n", *pmin);
char arr2[5] = {'a', 'b', 'c', 'd', 'e'};
char* pmin2 = minimum(arr2, 5,1, compare_chars); // sizeof(char) is 1
printf("Minimum value in the array is %c\n",*pmin2 );
return 0;
}
The output is (without any warnings) :
Minimum value in the array is 19
Minimum value in the array is a

what is the issue with copyArray func in this c program ? the copyArray function is not working properly

** I would like to copy the pointer array to a new pointer so the original array won't change**
/* The main contains a pointer (p) to an array */
int main()
{
...
...
...
p = (int*)malloc(length*sizeof(int));
z = (int*)copyArray(p, length);
printArray(z, length);
return 0;
}
/* end of main */
CopyArray func
/* copy the array, return a new pointer to a new array with same size and values */
int copyArray(int *p, int length)
{
int *z = (int*)malloc(length*sizeof(int));
for(length--; length>=0; length--)
{
z[length] = p[length];
}
return *z;
}
printArray func
/* The function receives a pointer to an array and it's length. it will print the values that the array contains by the order */
void printArray(int *p, int length)
{
int i = 0;
for(; i<length; i++)
{
printf("\n %d \n", p[i]);
}
}
Reason for not working : return *z; here you are returning only one element *(z+0) = z[0] not the whole array. Check the code below:
#include <stdio.h>
#include <stdlib.h>
int *copyArray(int *p, int length) // Change return type to `int *`
{
int *z = malloc(length * sizeof(int)); // No need to cast output of malloc
for (length--; length >= 0; length--)
{
z[length] = p[length];
}
return z; // return the pointer.
}
void printArray(int *p, int length)
{
int i = 0;
for (; i < length; i++)
{
printf("\n %d \n", p[i]);
}
}
int main()
{
int *p;
int *z;
int length =5;
p = malloc(length*sizeof(int)); // No need of casting
for(int i=0 ;i<length; i++)
{
p[i] = i; // assigning some values
}
z = copyArray(p, length); // Donot cast return of the function
printArray(z, length);
return 0;
}
The output is :
0
1
2
3
4

How to print void * array with printf when length, element size and format are known?

I've tried it this way. Then got rubbish in the output and figured out that I'm doing it the wrong way.
#include "stdlib.h"
#include "stdio.h"
/*
* Prints array from the anonymous array pointer.
*
* Returns 0 on success.
* Return -1 on failure.
*/
int print_array(const void *arr, size_t arr_len,
size_t elem_size, const char *format) {
for (size_t i = 0; i < arr_len; ++i)
if (printf(format, (char *) arr + i * elem_size) < 0)
return -1;
printf("\n");
return 0;
}
// Usage example
int main() {
const int n = 3;
int arr[n];
for (int i = 0; i < n; ++i)
arr[i] = i;
print_array(arr, n, sizeof(int), "%d ");
}
My code is supposed to work with different possible types. The type is actually deduced somewhere in the beginning of the execution and then this minimal description is used. Such trick nicely works with scanf as it takes pointer to an element rather than the element itself.
Such complexity is needed to conform the open-closed priciple and therefore minimise the number of swithes and conditionals in the code. I'm trying to concentrate actual type deducing in one place only.
I guess the same thing as with scanf should be possible somehow because printf is actually a variadic function which can take any values and parse them during runtime. Abusing "stdarg.h" might help somehow.
Of course I would like to have the solution that is not compiler-specific.
Instead of passing a formatting string, pass a function to print it, allowing the user to do whatever he wants/needs to print the actual data.
int print_array(const void *arr, size_t arr_len, size_t elem_size,
int (*print_elem)(const void *el, void *cookie), // I would add FILE* argument
void *cookie // allow users to pass additional context if they wanna
) {
for (size_t i = 0; i < arr_len; ++i) {
if (print_elem((char*)arr + i * elem_size, cookie) < 0) {
return -1;
}
}
printf("\n");
return 0;
}
int print_int(const void *el, void *cookie) {
return printf("%d", *(int*)el);
}
// print and allow users to pass options
int print_int_with_width(const void *el, void *cookie) {
int width = *(int*)cookie;
return printf("%*d", width, *(int*)el);
}
int arr[5];
int main() {
print_array(arr, 5, sizeof(int), print_int, NULL);
int width = 5;
print_array(arr, 5, sizeof(int), print_int_with_width, &width);
}
int print_array(const char *format, const void *arr, size_t arr_len, size_t elem_size, int fp)
{
const uint8_t *uarr = arr;
uint8_t u8;
uint16_t u16;
uint32_t u32;
uint64_t u64;
float f; double d;
int result;
for (size_t i = 0; i < arr_len; ++i)
{
switch(elem_size)
{
case 1:
memcpy(&u8, uarr + i, 1);
result = printf(format, u8);
break;
case 2:
memcpy(&u16, uarr + i * 2, 2);
result = printf(format, u16);
break;
case 4:
if(fp)
{
memcpy(&f, uarr + i * 4, 4);
result = printf(format, f);
}
else
{
memcpy(&u32, uarr + i * 4, 4);
result = printf(format, u32);
}
break;
case 8:
if(fp)
{
memcpy(&d, uarr + i * 8, 8);
result = printf(format, d);
}
else
{
memcpy(&u64, uarr + i * 8, 8);
result = printf(format, u64);
}
break;
default:
result = -1;
break;
}
}
return result;
}
// Usage example
int main()
{
const int n = 3;
int arr[n];
double arrd[3];
for (int i = 0; i < n; ++i)
{
arr[i] = i;
arrd[i] = 1.1 * i;
}
print_array("%d\n", arr, n, sizeof(*arr), 0);
print_array("%f\n", arrd, n, sizeof(*arrd), 1);
}
typedef int (*print_fn)(char*,void*);
int print_char (char *fmt, void *c) { return printf(fmt, *((char*) c)); }
int print_int (char *fmt, void *i) { return printf(fmt, *((int*) i)); }
int print_float (char *fmt, void *f) { return printf(fmt, *((float*) f)); }
int print_str (char *fmt, void *str) { return printf(fmt, *((char**) str)); }
// add more types here
int print_array (
void *arr,
size_t arr_len,
size_t elem_size,
char* fmt,
print_fn print_elem
){
for (void *end = arr + arr_len * elem_size; arr < end; arr += elem_size)
if (print_elem(fmt, arr) < 0)
return -1;
return 0;
}
Another way using a macro, you don't need to pass the size of each element:
#include <stdio.h>
#define print_array(format, array, elems) \
do { \
for (int ___ = 0; ___ < elems; ___++) \
printf(format, array[___]); \
printf("\n"); \
} while (0)
int main (void)
{
char *str[] = {"one", "two", "three"};
print_array("%s ", str, 3);
int arr[] = {1, 2, 3};
print_array("%d ", arr, 3);
return 0;
}
I use ___ as iterator to prevent shadowing/poluting variable names.
The advantage over a void * attached to a callback is that the compiler can detect wrong format specifiers, i.e. passing "%s " for the array of ints returns:
demo.c: In function ‘main’:
demo.c:16:22: warning: format ‘%s’ expects argument of type ‘char *’, but argument 2 has type ‘int’ [-Wformat=]
16 | print_array(arr, "%s ", 3);
| ^~~~~
demo.c:6:16: note: in definition of macro ‘print_array’
6 | printf(format, array[___]); \
| ^~~~~~
demo.c:16:24: note: format string is defined here
16 | print_array(arr, "%s ", 3);

Double Pointer Using Error

I am having a trouble while practicing double pointer
The Error is "EXE_BAD_ACCESS" in Xcode
#include <stdio.h>
/* Program to Get Min and Max Value
in Array */
void SaveValue(int **maxPtr, int **minPtr, int arr[])
{
int i;
**maxPtr=arr[0]; // Error Line
**minPtr=arr[0]; // Error Line
for(i=1; i<5; i++)
{
if(arr[i]>**maxPtr)
**maxPtr=arr[i];
else if(arr[i]<**minPtr)
**minPtr=arr[i];
}
}
int main()
{
int arr[5]={4, 5, 7, 2, 6};
int *maxptr;
int *minptr;
SaveValue(&maxptr, &minptr, arr);
printf("%d, %d \n", *maxptr, *minptr);
}
I've thought that *dptr of **dptr = &ptr is *ptr
and **dptr means variable which *ptr pointing.
so I assume that **dptr = arr[0] means save first num of arr by reference at variable which *ptr pointing!
but I experiencing access error now.. I will thank for your help!
void SaveValue(int **maxPtr, int **minPtr, int arr[]); provides pointers to pointers to int so use them as such.
void SaveValue(int **maxPtr, int **minPtr, int arr[])
{
int i;
*maxPtr=arr + 0; /* same as *maxPtr = &arr[0]; */
*minPtr=arr + 0; /* same as *maxPtr = &arr[0]; */
for(i = 1; i < 5; i++)
{
if(arr[i] > **maxPtr)
*maxPtr = arr + i; /* same as *maxPtr = &arr[i]; */
else if(arr[i] < **minPtr)
*minPtr = arr + i; /* same as *minPtr = &arr[i]; */
}
}
Also this interface is a bit dangerous and unflexible; so why not pass the size of the array as well:
void SaveValue(int **maxPtr, int **minPtr, int arr[], ssize_t s)
{
*maxPtr=arr + 0;
*minPtr=arr + 0;
for(--s; s >= 0; --s)
{
if(arr[s] > **maxPtr)
{
*maxPtr = arr + s;
}
else if(arr[i] < **minPtr)
{
*minPtr = arr + s;
}
}
}
Call the fcuntion like this:
SaveValue(&maxptr, &minptr, arr, sizeof arr/sizeof *arr);
As the return value of the function is unused we could utlize it to apply some error inidication to allow the user of the function to write more stable code:
int SaveValue(int ** maxPtr, int ** minPtr, int arr[], ssize_t s)
{
int result = 0;
if ((NULL == arr) || (NULL == maxPtr) || (NULL == minPtr) || (0 > s))
{
result = -1;
errno = EINVAL;
}
else
{
*maxPtr=arr + 0;
*minPtr=arr + 0;
for(--s; s >= 0; --s)
{
if(arr[s] > **maxPtr)
{
*maxPtr = arr + s;
}
else if(arr[i] < **minPtr)
{
*minPtr = arr + s;
}
}
}
return result;
}
Use it like this:
#include <stdio.h>
int SaveValue(int ** maxPtr, int ** minPtr, int arr[], ssize_t s);
int main(void)
{
int arr[5]={4, 5, 7, 2, 6};
int *maxPtr;
int *minPtr;
int result = SaveValue(&maxPtr, &minPtr, arr, sizeof arr/sizeof *arr);
if (-1 == result)
{
perror("SaveValue() failed")
}
else
{
printf("%d, %d \n", *maxPtr, *minPtr);
}
}
The pointer should be pointing to valid memory location before dereferencing it else it will lead to undefined behavior. Below changes will fix your error.
int max;
int min;
int *maxptr = &max;
int *minptr = &min;
There is no need of double pointer here change your function prototype to
void SaveValue(int *maxPtr, int *minPtr, int arr[])
Have
int max;
int min;
in main() and call this API accordingly
SaveValue(&max,&min,arr);
I'll assume your code is purely for pointer learning purposes and not an attempt to implement this operation in a practical situation. So if you want to have maxptr and minptr in main() pointing to the maximum and minimum values in arr[], I think you should change your double pointer assignments from **maxPtr=arr[0] to *maxPtr=&arr[0], so your code would become:
void SaveValue(int **maxPtr, int **minPtr, int arr[])
{
int i;
*maxPtr = &arr[0]; // Error Line
*minPtr = &arr[0]; // Error Line
for (i = 1; i < 5; i++) {
if (arr[i] > **maxPtr)
*maxPtr = &arr[i];
else if (arr[i] < **minPtr)
*minPtr = &arr[i];
}
}
In this case, when you make the assignments, you don't want to dereference the double pointers. Instead, you should assign it with the address of the element you want to show when you dereference them in main().
You don't need to use the double asterisk when initialize the maxPtr and minPtr pointers in the function SaveValue, neither in the for loop body. MaxPtr and minPtr both are double pointers, but is still the memory direction of maxptr in main(). So you only need to dereference them with a single asterisk, to acces the memory direction them points to.
The source correct source code is this:
#include <stdio.h>
/* Correct program to Get Min and Max Value in Array */
void SaveValue(int **maxPtr, int **minPtr, int arr[])
{
int i;
*maxPtr=arr[0];
*minPtr=arr[0];
for(i=1; i<5; i++)
{
if(arr[i]>*maxPtr)
*maxPtr=arr[i];
else if(arr[i]<*minPtr)
*minPtr=arr[i];
}
}
int main(void)
{
int arr[5]={4, 5, 7, 2, 6};
int *maxptr;
int *minptr;
SaveValue(&maxptr, &minptr, arr);
printf("%d, %d \n", maxptr, minptr);
return 0;
}
When I compile it with GCC and execute it, i get the next output:
7, 2.
Remember that depending of the environment (Operating System, version, compiler, standards) that you use the program results may vary.

Bubble Sort Trouble

gcc compiles the following code without error. I'm creating a bubble sort function that can be used with arrays of any data type (hence the function pointer).
It sorts the array of character strings (arr2) without a problem, however, I can't figure out why it won't properly sort the array of integers (arr). I added a printf statement in the compare_long function to see what is going on. It doesn't look like the integers are being passed to it properly. Any help will be greatly appreciated.
#include <stdio.h>
#include <string.h>
#define MAX_BUF 256
long arr[10] = { 3,6,1,2,3,8,4,1,7,2};
char arr2[5][20] = { "Mickey Mouse",
"Donald Duck",
"Minnie Mouse",
"Goofy",
"Pluto" };
void bubble(void *p, int width, int N, int(*fptr)(const void *, const void *));
int compare_string(const void *m, const void *n);
int compare_long(const void *m, const void *n);
int main(void) {
int i;
puts("\nBefore Sorting:\n");
for(i = 0; i < 10; i++) { /* show the long ints */
printf("%ld ",arr[i]);
}
puts("\n");
for(i = 0; i < 5; i++) { /* show the strings */
printf("%s\n", arr2[i]);
}
bubble(arr, 4, 10, compare_long); /* sort the longs */
bubble(arr2, 20, 5, compare_string); /* sort the strings */
puts("\n\nAfter Sorting:\n");
for(i = 0; i < 10; i++) { /* show the sorted longs */
printf("%d ",arr[i]);
}
puts("\n");
for(i = 0; i < 5; i++) { /* show the sorted strings */
printf("%s\n", arr2[i]);
}
return 0;
}
void bubble(void *p, int width, int N, int(*fptr)(const void *, const void *)) {
int i, j, k;
unsigned char buf[MAX_BUF];
unsigned char *bp = p;
for(i = N - 1; i >= 0; i--) {
for(j = 1; j <= i; j++) {
k = fptr((void *)(bp + width*(j-1)), (void *)(bp + j*width));
if(k > 0) {
memcpy(buf, bp + width*(j-1), width);
memcpy(bp + width*(j-1), bp + j*width , width);
memcpy(bp + j*width, buf, width);
}
}
}
}
int compare_string(const void *m, const void *n) {
char *m1 = (char *)m;
char *n1 = (char *)n;
return (strcmp(m1,n1));
}
int compare_long(const void *m, const void *n) {
long *m1, *n1;
m1 = (long *)m;
n1 = (long *)n;
printf("m1 = %l and n1 = %l\n", *m1, *n1);
return (*m1 > *n1);
}
The ANSI C spec defines long as a MINIMUM of 4 bytes (32 bits) but GCC is defining long as 8 bytes in your case. It is architecture-specific so you need to use sizeof(long) or one of the C99 types like uint32_t or int32_t if you want a specific size.

Resources