1

I'm generating a level using a function, and so I'm sending a pointer to pointer of my screen to update him. But when I try to use SDL_MapRGB i'm getting an error on the *screen->format part. Is there a way to do this ? Here's the code i'm using :

void generateLevel(SDL_Surface** screen)
{
    int i=0, j=0;
    char object =' ';
    FILE* level = NULL;
    SDL_Surface* lvl[LARGEUR_MAP][HAUTEUR_MAP];
    SDL_Rect posElem;

    //Ouverture du fichier contenant les infos du niveau
    level = fopen("lvl.txt","r");

    if(level == NULL)
    {
        fprintf(stderr,"Erreur lors de l'ouverture du fichier");
        exit(EXIT_FAILURE);
    }

    //Boucle pour lire le fichier et placer les éléments du décor
    for(j=0;j<HAUTEUR_MAP;j++)
    {
        for(i=0;i<LARGEUR_MAP;i++)
        {
            object = fgetc(level);
            if(object == '\n')
                object = fgetc(level);
            switch(object)
            {
                case 'm':
                    lvl[i][j] = IMG_Load("images\\mur.jpg");
                    posElem.x = i*TAILLE_BLOC;
                    posElem.y = j*TAILLE_BLOC;
                    SDL_BlitSurface(lvl[i][j], NULL, *screen, &posElem);
                    break;
            }


        }
    }

    SDL_FillRect(*screen, NULL, SDL_MapRGB(*screen->format,255,255,255));
    SDL_Flip(*screen);
    fclose(level);
}

The error comes on the end of the code, on the SDL_FillRect(); Everything's working fine but this, and I can't figure out how to do this. Tried with *screen->format, **screen->format, screen->format, and even &screen->format (how desperate I am ^^).

Edit : The error

error: request for member 'format' in '* screen', which is of pointer type 'SDL_Surface*' (maybe you meant to use '->' ?)"`

Sourav Ghosh
  • 133,132
  • 16
  • 183
  • 261
DoT
  • 369
  • 2
  • 12
  • 1
    how about `(*screen)->format`? – Sourav Ghosh Dec 19 '14 at 11:42
  • Perfect ! You're always here to help Sourav :) Can I ask you why it needs "()" ? – DoT Dec 19 '14 at 11:43
  • Its related with [operator precedence](http://en.cppreference.com/w/c/language/operator_precedence). Bit long to post as comment. I'll detail in my answer. :-) – Sourav Ghosh Dec 19 '14 at 11:44
  • Is there a reason your function accepts `SDL_Surface** screen` instead of just `SDL_Surface* screen`? You could avoid needing to deference `screen` twice everywhere (i.e., you could simply write `screen->format`) by changing this. – Julian Dec 19 '14 at 20:02
  • @AtlasC1 I'm starting this code. I Don't know what this function will contain and I hate making function with lot of arguments, so I prefer to use double pointer. But yes, for the moment I just could return my screen, it would be easier :) Edit : I'm saying stupid things (I just awaken, it must helps ^^). There's no relevance between the arguments and what the function returns. – DoT Dec 21 '14 at 14:59
  • A function needs to accept a pointer to a pointer only when said function may change what the pointer is pointing to, and you want this change to to be in effect outside of the function's scope. In other words, there is no reason to pass an `SDL_Surface**` here :) – Julian Dec 22 '14 at 15:39
  • @AtlasC1 Yep, I just modified it and it works. Don't know what I was thinking when I coded this. I hate pointers... :( – DoT Dec 24 '14 at 13:41

2 Answers2

3

TL;DR solution --> Change your code to (*screen)->format.

Reason:

As per the operator precedence rule,

The -> operator [Structure and union member access through pointer] has higher priority over the * [Indirection (dereference)] operator.

So, your code *screen->format, is effectively behaving like

 *(screen->format)

which means,

  1. it's trying to access the format member variable from screen pointer
  2. It's [ideally] trying to dereference screen->format.

But, as per the definition, SDL_Surface** screen, screen is SDL_Surface**, not SDL_Surface*. That's why you're getting the error.

What you want is actually to

  1. Dereference screen to get a SDL_Surface* pointer [(*screen)]
  2. Then, access the format member variable from that pointer. [(*screen)->format]
Sourav Ghosh
  • 133,132
  • 16
  • 183
  • 261
  • Wow ok. I'm looking at the link you gave me above in the same time ;) It's a bit tricky all of this ! I'll have to make my hand on this. Thanks for your clear explanation. – DoT Dec 19 '14 at 11:58
2

The unary * dereference operator has lower operator precedence than the structure pointer access operator ->. That means you're actually doing *(screen->format).

You need some parentheses to get the right precedence: (*screen)->format

Some programmer dude
  • 400,186
  • 35
  • 402
  • 621