You are not logged in.

#1 2011-07-28 10:22:25

Jordanlw
Member
Registered: 2010-07-27
Posts: 44

[SOLVED]Precedence problem in C

Hello, this is the line that's causing the problem:

#define SETPIXEL(surface,bits,x,y,pixel) surface->(Uint8 *)pixels[y * surface->w * bits + x * bits] = pixel

The problem occurs at the Uint8 pointer cast, here's the error:

error: expected identifier before ‘(’ token

I've tried many combinations of parenthesis, nothing seems to work.
Thanks.

Last edited by Jordanlw (2011-07-28 11:09:18)

Offline

#2 2011-07-28 10:48:27

KenJackson
Member
From: Maryland, USA
Registered: 2011-05-31
Posts: 18

Re: [SOLVED]Precedence problem in C

What types are surface and pixels?

If We assume
struct SOMETHING
{
    char *pixels;
    ...
} surface;

Then this might work:

#define SETPIXEL(surface,bits,x,y,pixel) ((Uint8 *)(surface->pixels))[...] = pixel

I don't think you can ever cast a struct or class member after the -> operator.

Also note, of course, to make it a good macro you should add a set of parenthesis around each of the arguments to avoid surprising results if, for example, you pass "var + 1" for x or y.

Offline

#3 2011-07-28 11:06:26

Jordanlw
Member
Registered: 2010-07-27
Posts: 44

Re: [SOLVED]Precedence problem in C

Thanks for your response, I can't believe I forgot one of the most important details, the types of the struct & child are listed at http://sdl.beuc.net/sdl.wiki/SDL_Surface. I didn't add any safety parenthesis because I didn't want to confuse myself with all of them until the end.
Thanks.

EDIT: Responded before testing your solution, everything seems to be working, thanks.

Last edited by Jordanlw (2011-07-28 11:09:03)

Offline

#4 2011-07-28 14:15:24

tavianator
Member
From: Waterloo, ON, Canada
Registered: 2007-08-21
Posts: 859
Website

Re: [SOLVED]Precedence problem in C

A safer version would be this:

#define SETPIXEL(surface, bits, x, y, pixel) ((void)(((Uint8 *)(surface)->pixels)[(y) * (surface)->w * (bits) + (x) * (bits)] = (pixel)))

To avoid evaluating surface and bits twice, you can do this:

#define SETPIXEL(surface, bits, x, y, pixel) \
  do { \
    type *realsurface = (surface); \
    type realbits = (bits); \
    (Uint8 *)realsurface->pixels)[(y) * realsurface->w * realbits + (x) * realbits] = (pixel); \
  } while (0)

It may be significantly nicer to do this, however:

inline void
set_surface_pixel(type *surface, type bits, type x, type y, Uint8 pixel)
{
  Uint8 *pixels = (Uint8 *)surface->pixels;
  pixels[y * surface->w * bits + x * bits] = pixel;
}

Last edited by tavianator (2011-07-28 14:15:55)

Offline

Board footer

Powered by FluxBB