Search code examples
cglobal-variablesextern

Extern in C - what am I doing wrong?


I'm playing around, making a small chessgame in C, cause I haven't touched C for years.

My main is a pretty simple test:

#include "ChessGame.h"

int main()
{
    initializeNewGame();
    onLift('a', '2');
    onSet('a', '3');
}

InitializeNewGame() is going to clear some buffers, and initialize the board. The board is a simple struct, defined in:

chessBoardStructure.h:

struct chessboard
{
    char board[8][8];
};

struct chessboard* board;

When initialize is called, it utilizes a header called Chessboard.h. This header has the responsibility of checking that the user is following the rules. It also knows how to initalize the board.

chessBoard.c

#include "chessBoardStructure.h"

extern struct chessboard * board;

void initializeBoard()
{
    board = malloc(sizeof(struct chessboard));
    /* Sets the array to the right chars */
 }

Now, from my understanding, I should now have defined the global variable, board. And to verify I print out the board after InitializeBoard() has been called from InitializeNewGame(). All seems fine.

Now the InitializeGame() returns to main, and onLift() is called. This should verify some rules. The problem is, when onLift() is called in ChessGame.c as:

ChessGame.c extern struct chessboard* board;

void onLift(char col, char row)
{

    short err = getValidMoves(liftedCol, liftedRow, &validEndPoints, &validRoads, board);
    if (err == -1)
        handleBadPiece();

    /* Do stuff */

}

The board is just full of -51. When I set a watch on the board in the header, I see it being initialized, and then when InitializeGame() exits scope, it becomes the good ol' -51.

What am I doing wrong here?

I miss C++. :-)

Thank you!

Edit small example I tried changing the extern around as proposed, but the same thing happened. See the below example.

main.c

#include "a.h"

int main()
{
    masterInitialize();
    printData();

    return 0;
}

(Headers not shown, due to just declarations)

a.c

#include "a.h"
#include "b.h"
#include "struct.h"
#include <stdio.h>

struct mystruct* datastruct;

void masterInitialize()
{
    initializeDataStruct();
}

void printData()
{
    for (int i = 0; i < 10; i++)
        printf("Data: %c\n", datastruct->data[i]);
}

b.c

#include "b.h"
#include "struct.h"
#include <stdlib.h>

struct mystruct* datastruct;

void initializeDataStruct()
{
    datastruct = malloc(sizeof(struct mystruct));
    for (int i = 0; i < 10; i++)
        datastruct->data[i] = 1;
}

struct.h

struct mystruct
{
    char data[10];
};

extern struct mystruct* datastruct;

Solution

  • You've got things the wrong way around.

    This should be in "chessBoard.c".

    struct chessboard* board;
    

    and this should be in your header

    extern struct chessboard * board;
    

    As that'll tell all the files where you include it that there exists the variable board declared somewhere and at link time, it'll use the one you've declared in "chessBoard.c"

    With the way you have it currently, each C file that includes the header will have it's own unique version of board