Thread: Function Ptrs and Void *

  1. #1
    Registered User
    Join Date
    Apr 2004
    Posts
    173

    Function Ptrs and Void *

    Hmm I'm having trouble compiling a program from a book - I've tripled check to see if I got it right and I just can't see it. The compiler gives an error about 'void * being an unknown size'. The problem is in the is_sorted function.

    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    int is_sorted(void *A, int nelem, int size, int (*cmp)(void *, void *));
    
    int double_ascending(void *v1, void *v2)
    {
    	double *d1 = v1;
    	double *d2 = v2;
    	if (d1 < d2)
    		return -1;
    	if (d1 > d2)
    		return 1;
    	return 0;
    }
    
    int string_descending(void *v1, void *v2)
    {
    	char **s1 = v1;
    	char **s2 = v2;
    	return -strcmp(*s1,*s2);
    }
    
    int main(int argc, char **argv)
    {
    	double X[] = {1.87, 3.43, 7.64};
    	char *S[] = {"wombat", "wallaby", "quoll", "quokka"};
    
    	if (is_sorted(X, sizeof(X)/sizeof(*X), sizeof(*X), double_ascending))
    	{
    		printf("Array X is ascending\n");
    	} else { printf("Array X is descending\n"); }
    
    	if (is_sorted( S, sizeof(S)/sizeof(*S), sizeof(*S), string_descending))
    	{
    		printf("Array S is descending\n");
    	} else { printf("Array S is ascending\n"); }
    
    	return 0;
    }
    
    int is_sorted(void *A, int nelem, int size, int (*cmp)(void *, void *))
    {
    	while (nelem > 1)
    	{
    		if (cmp(A, A+size) > 0) { // <-- PROBLEM HERE
    			return 0;	// out of order
    		}
    		A += size; // <-- PROBLEM HERE
    		nelem -= 1;
    	}
    	// all elements have been checked
    	return 1;
    }
    I'm not exactly sure why its generating an error as it makes sense to me (unfortunately not to the comp) but any suggestions on what is wrong would definitely be helpful! Thanks!

  2. #2
    Quote Originally Posted by 0rion
    Hmm I'm having trouble compiling a program from a book - I've tripled check to see if I got it right and I just can't see it. The compiler gives an error about 'void * being an unknown size'.
    My guess is that you attempted to dereference a void pointer, that is not allowed by the C language.
    The problem is in the is_sorted function.

    Code:
    int is_sorted(void *A, int nelem, int size, int (*cmp)(void *, void *))
    {
    	while (nelem > 1)
    	{
    		if (cmp(A, A+size) > 0) { // <-- PROBLEM HERE
    			return 0;	// out of order
    		}
    		A += size; // <-- PROBLEM HERE
    		nelem -= 1;
    	}
    	// all elements have been checked
    	return 1;
    }
    Note that is the author of the book claims that this code is compiling, just let him know that gcc extensions are not the standard...

    Ok You definitely can't do pointer arithmetics on a void*. You must use a local unsigned char*, for example.
    Code:
    int is_sorted(void *A, int nelem, int size, int (*cmp)(void *, void *))
    {
    	while (nelem > 1)
    	{
                unsigned char *p = A;
    
    		if (cmp(p, p+size) > 0) {
    			return 0;	// out of order
    		}
    		p += size;
    		nelem -= 1;
    	}
    	// all elements have been checked
    	return 1;
    }
    Nice code anyway, showing how useful can be pointers to functions and callbacks.

    I guess that your next exercise will be about sorting some array. (Like the standard 'qsort()' function).
    Emmanuel Delahaye

    "C is a sharp tool"

  3. #3
    Registered User
    Join Date
    Mar 2003
    Posts
    143
    The problem is that pointer arithmetic is not like normal arithmetic as shown by this code:
    Code:
    #include <stdio.h>
    
    int main (void)
    {
      int a = 0;
      int * pA = &a;
      int * pB;
    
      pB = pA + 1;
    
      printf("pA = %p; pB = %p\n", pA, pB);
    
      return 0;
    }
    
    my output:
    pA = 0012FF7C; pB = 0012FF80
    so adding 1 actually adds 4 to the pointer value. This is because (on my compiler)
    sizeof(int) = 4. This is very useful for stepping through arrays of data for example.

    The problem comes when A is a void pointer (as in your case). The compiler doesn't
    know how big what your pointer is pointer to is so cannot do the pointer arithmetic.

    One solution (its not particularly clean and there may be a better way to do it) is this:
    Code:
    if (cmp(A, (void*)((int)A+size)) > 0) { 
      return 0;	// out of order
    }
    A = (void*)((int)A+size); 
    nelem -= 1;
    ::EDIT - ok, yes, Emmanuel's way is cleaner. I knew there must be a better way...
    Last edited by DavT; 08-02-2004 at 06:19 AM.
    DavT
    -----------------------------------------------

  4. #4
    ... kermit's Avatar
    Join Date
    Jan 2003
    Posts
    1,534
    You know it is funny that the code the OP posted compiled on my machine with -Wall, and it did not so much as hiccup..

    That is interesting.

  5. #5
    Quote Originally Posted by kermit
    You know it is funny that the code the OP posted compiled on my machine with -Wall, and it did not so much as hiccup..

    That is interesting.
    Because it's a well known gcc extension. void* is considered like char *. I don't know how to disable this so-called 'feature' that misleads people into writing non-portable code without a warning...
    Emmanuel Delahaye

    "C is a sharp tool"

  6. #6
    ... kermit's Avatar
    Join Date
    Jan 2003
    Posts
    1,534
    Ack - even splint does not catch this problem. A good reason not to rely overly much on these handy tools...

  7. #7
    Registered User
    Join Date
    Apr 2004
    Posts
    173
    Ahh thanks for the input ppl!
    Yer the textbook wuz written by the one of the profs at my uni and not many ppl have it outside the uni so dats why there are still some slight errors in the coding.

  8. #8
    & the hat of GPL slaying Thantos's Avatar
    Join Date
    Sep 2001
    Posts
    5,681
    I don't know how to disable this so-called 'feature' that misleads people into writing non-portable code without a warning...
    use -pedantic it disables all extensions

  9. #9
    Quote Originally Posted by 0rion
    Ahh thanks for the input ppl!
    Yer the textbook wuz written by the one of the profs at my uni and not many ppl have it outside the uni so dats why there are still some slight errors in the coding.
    Could you please rephrase in plain English. English is not my first language, and I don't understand what you have written.
    Emmanuel Delahaye

    "C is a sharp tool"

  10. #10
    ... kermit's Avatar
    Join Date
    Jan 2003
    Posts
    1,534
    Quote Originally Posted by 0rion
    Ahh thanks for the input ppl!
    Yer the textbook wuz written by the one of the profs at my uni and not many ppl have it outside the uni so dats why there are still some slight errors in the coding.
    translation:

    Yeah, the textbook was written by one of the professors at the university I attend, and not many people outside of the university have a copy. That is why there are still some slight errors in the coding.



    ~/

  11. #11
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    Quote Originally Posted by kermit
    translation:
    Yeah, the textbook was written by one of the professors at the university I attend, and not many people outside of the university have a copy. That is why there are still some slight errors in the coding.
    Translation:

    I have a lousy professor, who wrote this book, which is why there are still some errors in the code.

    ?!

    Quzah.
    Hope is the first step on the road to disappointment.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. struct ptrs to struct ptrs
    By lolguy in forum C Programming
    Replies: 5
    Last Post: 02-24-2009, 12:02 AM
  2. How to write my own qsort routine
    By tonbarius in forum C Programming
    Replies: 3
    Last Post: 05-14-2006, 12:34 PM
  3. passing 2D array of ptrs as parameter
    By Psycho in forum C++ Programming
    Replies: 3
    Last Post: 06-13-2003, 10:13 AM
  4. problem with -> notation and using a "general" header file
    By Yourhighness in forum C Programming
    Replies: 2
    Last Post: 06-08-2003, 08:39 AM
  5. Still having a little trouble w/th ptrs
    By Yourhighness in forum C Programming
    Replies: 15
    Last Post: 05-20-2003, 02:41 AM