2

I'm building a basic card game, and for that I must create a deck of card (not a regular deck of cards though) and shuffle it. It was working quite well on Visual Studio (Windows 10), but once I switched to Xcode (Mac OS X 10.11.16) I can't seem to get the same results.

Here is my main.c, referencing my .h file:

#include "Card.h"
#include <stdio.h>
#include <string.h>
#include <stdlib.h>


int main(void){

    Card* lst = NULL;

    if(CRD_createDeck(lst) != CRD_retCondOK)
        printf("Something is wrong\n");
    CRD_showDeck(b);

    if(b == NULL)
        printf("Empty\n");

    return 0;
}

My Card.h file defines Card* b:

static Card* b;

And my Card.c file:

#include "Card.h"
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <time.h>

CRD_tpRetCond CRD_createDeck(Card* lst){

    int numCards, numSuits, CardEnum = 1;
    char vetCardName[10] = {'4', '5', '6', '7', 'Q', 'J', 'K', 'A', '2', '3'};
    char vetCardSuit[4][8] = {"Ouros", "Espadas", "Copas", "Paus"};

    /*
     lst = CRD_createList();
     if(lst != NULL)
     return CRD_retCondCreateError;*/

    CardInfo* generico;
    for(numSuits = 4; numSuits >= 1; numSuits--){
        for(numCards=10;numCards >= 1; numCards--) {
            generico = CRD_createCard(vetCardName[numCards-1],numCards,vetCardSuit[numNaipes-1],numSuits);
            lst = CRD_insertCard(lst,generico,CardEnum);
            CardEnum++;
        }
    }
    b = lst;
    CRD_showDeck(b);
    return BAR_CondRetOK;
}

I apologize if there are any inconsistencies with the variable names, I quickly translated from portuguese to English to give you all a better idea. When I call the function CRD_showDeck(b), it correctly shows all of the cards in the deck. However, my main function considers b to be empty. Why is this happening?

Rodrigo Veiga
  • 125
  • 1
  • 1
  • 8

1 Answers1

1

A static variable limits the scope of the variable to the file. So, declaring a variable to be static in a header file ends up creating distinct variables in each source file that includes the header. Each one with its scope limited to that source file. Thus, changing the variable value in one translation unit has no effect on the copy created in each of the other translation units.

A truly global variable (seen by each translation unit) should be declared extern in the header file, and should be defined in exactly one of the source files. Given the name of your source files, I would probably opt to add the line:

Card* b;

In Card.c, and change static to extern in the header file.

jxh
  • 69,070
  • 8
  • 110
  • 193
  • That makes sense, but once I try to correct this I receive the following error messages: Undefined symbols for architecture x86_64: "_b", referenced from: _main in main.o _CRD_createDeck in Card.o ld: symbol(s) not found for architecture x86_64 clang: error: linker command failed with exit code 1 (use -v to see invocation) – Rodrigo Veiga Apr 30 '18 at 21:31
  • 1
    *and should be **defined** in exactly one of the source files.* Add `Card *b;` to `Card.c`. – jxh Apr 30 '18 at 21:33
  • https://stackoverflow.com/questions/1433204/how-do-i-use-extern-to-share-variables-between-source-files?rq=1 – jxh Apr 30 '18 at 21:34