Thread: More pointer problems :(

  1. #1
    Dr Dipshi++ mike_g's Avatar
    Join Date
    Oct 2006
    Location
    On me hyperplane
    Posts
    1,218

    More pointer problems :(

    No matter what I seem to try whenever I compile my prog I get ther following error:
    Code:
    warning: passing argument 1 of ‘blit_and_fade’ from incompatible pointer type
    Heres my best guess, main:
    Code:
    #include "screen.h"
    #include "vector.h"
    
    SDL_Surface *screen = NULL;
    SDL_Event event; 
    
    int main()
    {
    	screen = SDL_SetVideoMode(GRAPHICS_W, GRAPHICS_H, 32, SDL_SWSURFACE);	
    	Uint32 buffer[SCREEN_BUFFER_SIZE]={0xFFFFFFFF};
    	while(1)
    	{
    		blit_and_fade(&buffer, &screen, SCREEN_BUFFER_SIZE, 0.95);
    		SDL_Flip(screen);
    		while(SDL_PollEvent(&event))if(event.type==SDL_KEYDOWN) break;
    	}
    	return 0;
    }
    and function:
    Code:
    void blit_and_fade(Uint32 **src, SDL_Surface **dst, Uint32 size, float mod)
    {
    	Uint32 *pix = (Uint32*)(*dst)->pixels;
    	Uint32 *buf = (*src);	
    	Uint32 r_b, g;
    	int fade = (int) (mod * 256.0);
    
    	for(int i=0; i<size; i++, pix++, buf++)
    	{
    		*pix = *buf;	
    		r_b = (((*buf & 0x00FF00FF) * fade) & 0xFF00FF00) >> 8;		
    		g   = (((*buf & 0x0000FF00) * fade) & 0x00FF0000) >> 8;				
    		*buf = r_b | g;
    	}
    }
    How cn I get my pointer types compatible?

  2. #2
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    Use Uint32 (*src)[] instead, perhaps (since &buffer is a pointer to an array, which is not a pointer to a pointer).

  3. #3
    Dr Dipshi++ mike_g's Avatar
    Join Date
    Oct 2006
    Location
    On me hyperplane
    Posts
    1,218
    I tried that but gcc still gives me the same warning. Thanks for the suggestion tho.

  4. #4
    Dr Dipshi++ mike_g's Avatar
    Join Date
    Oct 2006
    Location
    On me hyperplane
    Posts
    1,218
    I changed the Uint32 to unsigned long and for some reason the warnings went away and the prog works w/o segfaulting any more.

  5. #5
    Registered User
    Join Date
    Feb 2008
    Posts
    5
    Quote Originally Posted by mike_g View Post
    I changed the Uint32 to unsigned long and for some reason the warnings went away and the prog works w/o segfaulting any more.
    Your solution is correct and will work because you are passing an address to blit_and_fade(), and the type used for addresses in most systems is unsigned long.

    But a more precise solution would be to explicitly tell the compiler that you are indeed passing a pointer-to-pointer of a Uint32.

    Code:
    	while(1)
    	{
    		blit_and_fade((Uint32 **)&buffer, &screen, SCREEN_BUFFER_SIZE, 0.95);
    		...

  6. #6
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Casts are best avoided, though, since if the cast is incorrect you won't get a warning and may cause errors.
    Btw, since it's an array, you can pass it as a simple pointer. It will pass the address to the first element and as thus, you can change it from blit_and_fade w/o problems. Change it to Uint32* and remove the & and you should get no warnings.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  7. #7
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Quote Originally Posted by mageshd84 View Post
    Your solution is correct and will work because you are passing an address to blit_and_fade(), and the type used for addresses in most systems is unsigned long.
    The type "unsigned long" may well be "the same size as an address", but it's absolutely not the same as a an address. An address is a pointer. It may possibly be that unsigned long in this case doesn't generate the same warning - to mike_g: are you using -Wall for gcc? If not, do so.

    Please post the current version of the code - and I'd also like to point out that tabstop is right; you will not automatically convert the address of an array to a pointer to pointer that you can use as an array of pointers. In this case it's OK, because you are just taking the pointer and loading what it points at. There is no need to use the double pointer mechanism here.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  8. #8
    Dr Dipshi++ mike_g's Avatar
    Join Date
    Oct 2006
    Location
    On me hyperplane
    Posts
    1,218
    matsp: Yeah I always compile with -Wall. That was the only warning I was getting. My current code is doing what tabstop suggested:
    Code:
    #include "screen.h"
    #include "vector.h"
    
    SDL_Surface *screen = NULL;
    SDL_Event event; 
    
    int main()
    {
    	screen = SDL_SetVideoMode(GRAPHICS_W, GRAPHICS_H, 32, SDL_SWSURFACE);	
    	long buffer[SCREEN_BUFFER_SIZE];	
    	for(int i=0; i<SCREEN_BUFFER_SIZE; i++) buffer[i]=0xFFFFFFFF;
    
    	int quit = 0;	
    	while(! quit)
    	{
    		blit_and_fade(&buffer, &screen, SCREEN_BUFFER_SIZE, 0.9);
    		SDL_Flip(screen);
    		while(SDL_PollEvent(&event)) if(event.type==SDL_KEYDOWN) quit = 1;
    		SDL_Delay(20);
    	}
            return 0;
    }
    and:
    Code:
    void blit_and_fade(long (*src)[], SDL_Surface **dst, Uint32 size, float mod)
    {
    	Uint32 *pix = (Uint32*)(*dst)->pixels;
    	Uint32 *buf = (Uint32*)(*src);	
    	Uint32 r_b, g;
    	int fade = (int) (mod * 256.0);
    
    	for(int i=0; i<size; i++, pix++, buf++)
    	{
    		*pix = *buf;	
    		r_b = ((( *buf & 0x00FF00FF) * fade) & 0xFF00FF00) >> 8;		
    		g   = ((( *buf & 0x0000FF00) * fade) & 0x00FF0000) >> 8;				
    		*buf = r_b | g;
    	}
    }
    Which was working w/o errors or warnings.

    In vector.h I had these defined:
    Code:
    #ifndef Uint8
    	#define Uint8 unsigned char
    #endif 
    #ifndef Uint16
    	#define Uint16 unsigned short
    #endif 
    #ifndef Uint32
    	#define Uint32 unsigned long
    #endif
    but the Uints are also defined in SDL. Could this be causing a problem?

  9. #9
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Quote Originally Posted by mike_g View Post
    matsp: Yeah I always compile with -Wall. That was the only warning I was getting. My current code is doing what tabstop suggested:
    [snip]
    In vector.h I had these defined:
    Code:
    #ifndef Uint8
    	#define Uint8 unsigned char
    #endif 
    #ifndef Uint16
    	#define Uint16 unsigned short
    #endif 
    #ifndef Uint32
    	#define Uint32 unsigned long
    #endif
    but the Uints are also defined in SDL. Could this be causing a problem?
    You probably should:
    1. use typedef instead of #define.
    2. try to use the same types in both places (that is, use SDL's header file to get the types).

    The warning may actually be caused by mixing unsigned long with unsigned int - they may be the same size but are not the same thing to the compiler. In most systems unsigned int and unsigned long are the same size, but should you find your code compiling on a system where they aren't, you'll be real thankful for the compiler warning you when you have them mixed up and fixing them.

    I still don't see the need for &buffer - why not pass just buffer.


    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  10. #10
    Dr Dipshi++ mike_g's Avatar
    Join Date
    Oct 2006
    Location
    On me hyperplane
    Posts
    1,218
    Ok I replaced the #defines with typedefs, changed the code so that its passing on buffer, reverted the long to Uint32 in the function. It works now with no warnings and the code is a little bit tidier. Thanks matsp.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Problems with passing an array of structures by pointer
    By raptor1770 in forum C Programming
    Replies: 9
    Last Post: 11-29-2008, 11:01 AM
  2. Replies: 2
    Last Post: 07-11-2008, 07:39 AM
  3. Following CTools
    By EstateMatt in forum C Programming
    Replies: 5
    Last Post: 06-26-2008, 10:10 AM
  4. Request for comments
    By Prelude in forum A Brief History of Cprogramming.com
    Replies: 15
    Last Post: 01-02-2004, 10:33 AM
  5. base class pointer problems
    By ... in forum C++ Programming
    Replies: 3
    Last Post: 11-16-2003, 11:27 PM