Thread: Why gcc cannot resolve symbol?

  1. #1
    Registered User
    Join Date
    Feb 2019
    Posts
    69

    Why gcc cannot resolve symbol?

    Hey

    following code seems not create a warning:

    Code:
    /* * main.c
     *
     *  Created on: Jul 21, 2019
     *      Author: Niclas Schwalbe
     */
    #include <stdlib.h>
    #include <stdio.h>
    #include "board.h"
    #include "chess.h"
    #include "odinutilities.h"
    
    
    
    
    void printBoard(BOARD_STATE* state){
    	for(int i = BOARD_LEN-1; i >= 0; i--){
    		for(int k = 0; k < BOARD_LEN; k++){
    			printf("%d,", (state->board[i][k]));
    		}
    		printf("\n");
    	}
    }
    
    
    char* create_move_string(char from_x, char from_y, char to_x, char to_y, char promotion_piece) {
    	char* move = malloc(CHARS_TO_EXPRESS_MOVE); //WARNING SYMBOLS CHARS_TO_EXPRESS_MOVE COULD NOT BE RESOLVED
    	move[0] = from_x;
    	move[1] = from_y;
    	move[2] = to_x;
    	move[3] = to_y;
    	move[4] = promotion_piece;
    	return move;
    }
    
    
    void printMoves(char** moves, size_t length, char translate_for_human){
    
    
    }
    Code:
    #include "board.h"#include "odinutilities.h"
    #ifndef CHESS_H
    #define CHESS_H
    
    
    #define PAWNS_DEGREES_OF_FREEDOM 3
    #define CHARS_TO_EXPRESS_MOVE 5
    
    
    enum piece {free_piece, pawn, knight, bishop, rock, queen, king};
    enum color {white, black};
    
    
    typedef struct {
    	BOARD_STATE board_state;
    	FILE* plast_moves_file;
    } CHESS_STATE;
    
    
    
    
    #endif
    Problem description: Symbol 'CHARS_TO_EXPRESS_MOVE'
    could not be resolved

    Can you figure out why?

    Thanks!

  2. #2
    Registered User
    Join Date
    May 2009
    Posts
    4,183
    Best guess you defined CHESS_H in another header file.
    "...a computer is a stupid machine with the ability to do incredibly smart things, while computer programmers are smart people with the ability to do incredibly stupid things. They are,in short, a perfect match.." Bill Bryson

  3. #3
    Programming Wraith GReaper's Avatar
    Join Date
    Apr 2009
    Location
    Greece
    Posts
    2,739
    You shouldn't do anything before or after the include guards. They're there to prevent you from including the file multiple times.
    Devoted my life to programming...

  4. #4
    Registered User
    Join Date
    Feb 2019
    Posts
    69
    Hmm. This is my source code:

    Everything movd to the includes...

    Odin.zip

  5. #5
    Registered User
    Join Date
    May 2019
    Posts
    214
    Ok, first - odinutilities.h includes itself, creating an infinite loop which ends up crashing the compiler.

    It should give an error regarding too many include files, but that depends on the compiler.

    After that...however the compiler tries to go on could generate meaningless complaints as the result of an internal crash.

    Beyond that, board.c has no chance of compiling, as it depends on material not included. Not sure why it's a .c, maybe it is material that should be in .h, because, among other things, return_all_pawn_moves is declared inline, which would have no meaning in a .c file unless the call to that function appears later in that c file.
    Last edited by Niccolo; 07-22-2019 at 04:56 PM.

  6. #6
    Registered User
    Join Date
    May 2009
    Posts
    4,183
    Including random includes in header files is a bad habit to have.

    Edit: Having a line in a files saying its main.c when it is odinutilities.c is a worse habit.
    Edit2: I would fix odinutilities.h for the problems mentioned by Niccolo.

    Tim S.
    Last edited by stahta01; 07-22-2019 at 07:59 PM.
    "...a computer is a stupid machine with the ability to do incredibly smart things, while computer programmers are smart people with the ability to do incredibly stupid things. They are,in short, a perfect match.." Bill Bryson

  7. #7
    Registered User
    Join Date
    Feb 2019
    Posts
    69
    Quote Originally Posted by stahta01 View Post
    Including random includes in header files is a bad habit to have.

    Edit: Having a line in a files saying its main.c when it is odinutilities.c is a worse habit.
    Edit2: I would fix odinutilities.h for the problems mentioned by Niccolo.

    Tim S.
    Hmm. I amnot sure what you mean by 1.

    Thanks for the support to everyone!


    Odin.zip

    Could someone explain to me how to "manage" mutiple files in C-projects?
    Last edited by SuchtyTV; 07-23-2019 at 06:43 AM.

  8. #8
    Registered User
    Join Date
    May 2009
    Posts
    4,183
    Having headers included in a header files that is not needed by the header itself is a bad habit.

    Note: It is common to have a single header that is designed to be a pre-compiled header that does include all or most headers needed by the project. But, this header normally does not do anything but include other headers.

    Tim S.
    "...a computer is a stupid machine with the ability to do incredibly smart things, while computer programmers are smart people with the ability to do incredibly stupid things. They are,in short, a perfect match.." Bill Bryson

  9. #9
    Registered User
    Join Date
    May 2009
    Posts
    4,183
    Quote Originally Posted by SuchtyTV View Post
    Could someone explain to me how to "manage" mutiple files in C-projects?
    What IDE are you using?
    Or are you using a makefile?

    Tim S.
    "...a computer is a stupid machine with the ability to do incredibly smart things, while computer programmers are smart people with the ability to do incredibly stupid things. They are,in short, a perfect match.." Bill Bryson

  10. #10
    Registered User
    Join Date
    Feb 2019
    Posts
    69
    Quote Originally Posted by stahta01 View Post
    What IDE are you using?
    Or are you using a makefile?

    Tim S.
    I use eclipse!

  11. #11
    Registered User
    Join Date
    Feb 2019
    Posts
    69
    Quote Originally Posted by SuchtyTV View Post
    I use eclipse!
    Hey! I am still looking for a answer.

  12. #12
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,660
    Does board need to know about chess?
    What if the game was checkers / draughts?

    Before you start writing code, you need some idea of a design. This enables you to keep all the related things in one place.

    Putting random bits of functionality all over the place just leads to spaghetti code.

    Some general approaches.
    1. Consistency of include order.
    I prefer the most general to most specific order, so standard library, platform specific, 3rd party libraries, your libraries, your module.

    2. Use the bare minimum of includes to achieve compilation. So don't include a bunch of files just for fun.

    3. Header files must be self-contained. People shouldn't have to guess what other header files they need by just including a file.
    So odinutilities.c has stdlib.h because of malloc, and odinutilities.h has stdlib.h because of size_t.

    Eg
    Code:
    File=board.c
    ==========
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    #include "chess.h"
    #include "odinutilities.h"
    
    char return_all_pawn_moves(char copy_board[8][8], char from_x, char from_y, MOVE_DATA* move_info, char color){
    	const char dy = color ? -1 : 1;
    	const unsigned char y = from_y + dy;
    	for (char m = -1; m < 1; m++) {
    		const unsigned char x = from_x + m;
    		if(move_info->array_size == move_info->used_array_size){
    			char* p= realloc((void*)move_info->moves, 2*(move_info->array_size));
    			move_info->array_size = 2*(move_info->array_size);
    			if(!p){
    				return -1;
    			}
    		}
    		if (m != 0) {
    			//check if pawn can take left and right
    			if(((y >= 0) & (y <= 7)) & (x >= 0) & (x <= 7) & (copy_board[y][x]*color < 0)) {
    				move_info->moves[move_info->used_array_size++] = create_move_string(from_x,from_y,x,y,(char)0);
    			}
    			// Add e.p.
    		} else {
    			if(copy_board[y][x] != 0) {
    				move_info->moves[move_info->used_array_size++] = create_move_string(from_x,from_y,x,y,(char)0);
    			}
    		}
    	}
    	return 0;
    }
    char** return_all_legal_moves(BOARD_STATE* plegal_board_state,char ignore_check) {
    	MOVE_DATA move_data;
    	move_data.array_size = MOVE_ARRAY_SIZE_BY_INIT;
    	move_data.used_array_size = 0;
    	move_data.moves = (char**)malloc(move_data.array_size * sizeof(char*));
    	char copy_board[8][8];
    	memcpy(copy_board, (plegal_board_state->board), sizeof(copy_board));
    	for (int i = 0; i < BOARD_LEN; i++) {
    		for (int k = 0; k < BOARD_LEN; k++) {
    			char piece = copy_board[i][k];
    			char color = piece < 0;
    			switch (copy_board[i][k]) {
    			case free_piece:
    				continue;
    			case pawn:
    				return_all_pawn_moves(copy_board,k,i,&move_data, color);
    				continue;
    
    			}
    		}
    	}
    	return NULL;
    }
    File=board.h
    ==========
    #ifndef BOARD_H
    #define BOARD_H
    
    #define BOARD_LEN 8
    #define MOVE_ARRAY_SIZE_BY_INIT 20
    
    #include <stdlib.h>
    
    typedef struct  {
    	char board[8][8];
    	char to_move;
    	char pieces_moved[6];
    } BOARD_STATE;
    
    typedef struct {
    	char** moves;
    	size_t array_size;
    	size_t used_array_size;
    } MOVE_DATA;
    
    //char** return_all_moves(BOARD_STATE* pstate);
    char** return_all_legal_moves(BOARD_STATE* pstate, char ignore_check);
    //char board_is_legal(BOARD_STATE* pstate);
    
    char return_all_pawn_moves(char copy_board[8][8], char from_x, char from_y, MOVE_DATA* move_info, char color);
    
    #endif
    File=chess.c
    ==========
    File=chess.h
    ==========
    #ifndef CHESS_H
    #define CHESS_H
    
    #include <stdio.h>
    
    #include "board.h"
    
    #define PAWNS_DEGREES_OF_FREEDOM 3
    #define CHARS_TO_EXPRESS_MOVE 5
    
    enum piece {free_piece, pawn, knight, bishop, rock, queen, king};
    enum color {white, black};
    
    typedef struct {
    	BOARD_STATE board_state;
    	FILE* plast_moves_file;
    } CHESS_STATE;
    
    #endif
    File=main.c
    ==========
    #include <stdio.h>
    #include <stdlib.h>
    #include <ctype.h>
    
    #include "chess.h"
    #include "odinutilities.h"
    
    //-1,-1,-1,-1,-1,-1,-1,-1\n <-- 3chars * 8
    #define MAX_CHARS_PER_ROW 24
    
    void loadBoard(BOARD_STATE* pboard_state, FILE* write);
    
    int main(int argc, char* argv[]) {
    	if (argc != 2) {
    		fprintf(stderr, "Error: Add filepath to a chessposition");
    		return EXIT_FAILURE;
    	}
    	FILE* pchess_file = fopen(argv[1], "r");
    	CHESS_STATE chess_state;
    
    	loadBoard(&chess_state.board_state, pchess_file);
    	printBoard(&chess_state.board_state);
    	//valdiate board
    
    }
    
    void loadBoard(BOARD_STATE* pboard_state, FILE* pchess_file){
    	for (int i = 0; i < 9; i++) {
    
    		char* line = malloc(MAX_CHARS_PER_ROW);
    		fgets(line, MAX_CHARS_PER_ROW, pchess_file);
    
    		enum {comma, sign, digit, error};
    		int state = comma;
    		char presign = 1;
    		char result;
    
    		if (i < 8) {
    			int n = 0;
    			for (int k = 0; k < MAX_CHARS_PER_ROW; k++) {
    				char c = line[k];
    				if(n == 7){
    					break;
    				}
    				switch (state) {
    				case comma:
    					if (c == '+') {
    						state = sign;
    						presign = 1;
    						break;
    					}
    					if (c == '-') {
    						state = sign;
    						presign = -1;
    						break;
    					}
    					if (isdigit(c)) {
    						presign = 1;
    						result = presign * (c - '0');
    						state = digit;
    						break;
    					}
    					state = error;
    					break;
    				case sign:
    					if (isdigit(c)) {
    						state = digit;
    						result = presign * (c - '0');
    						break;
    					}
    					state = error;
    					break;
    				case digit:
    					if (c == ',') {
    						pboard_state->board[i][n++] = result;
    						state = comma;
    						break;
    					}
    					if ((c == '\n') & (n == 6)) {
    						pboard_state->board[i][n++] = result;
    						n = 0;
    						state = comma;
    						break;
    					}
    					state = error;
    					break;
    				default:
    					fprintf(stderr, "Error in POS %d,%d",i, n);
    					exit(EXIT_FAILURE);
    				}
    			}
    		} else {
    			char c = line[0];
    			if(c == '1' || c == '0'){
    				pboard_state->to_move = c-'0';
    				return;
    			}
    			fprintf(stderr, "Error in File");
    			exit(EXIT_FAILURE);
    		}
    	}
    }
    File=odinutilities.c
    ==========
    #include <stdio.h>
    #include <stdlib.h>
    
    #include "odinutilities.h"
    #include "chess.h"
    
    void printBoard(BOARD_STATE* state){
    	for(int i = BOARD_LEN-1; i >= 0; i--){
    		for(int k = 0; k < BOARD_LEN; k++){
    			printf("%d,", (state->board[i][k]));
    		}
    		printf("\n");
    	}
    }
    
    char* create_move_string(char from_x, char from_y, char to_x, char to_y, char promotion_piece) {
    	char* move = malloc(CHARS_TO_EXPRESS_MOVE);
    	move[0] = from_x;
    	move[1] = from_y;
    	move[2] = to_x;
    	move[3] = to_y;
    	move[4] = promotion_piece;
    	return move;
    }
    
    void printMoves(char** moves, size_t length, char translate_for_human){
    
    }
    File=odinutilities.h
    ==========
    #ifndef ODINUTILITIES_H
    #define ODINUTILITIES_H
    #include <stdlib.h>
    #include "board.h"
    
    void printMoves(char** moves, size_t length, char translate_for_human);
    void printBoard(BOARD_STATE* state);
    char* create_move_string(char from_x, char from_y, char to_x, char to_y, char promotion_piece);
    
    #endif
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  13. #13
    Registered User
    Join Date
    May 2009
    Posts
    4,183
    Quote Originally Posted by SuchtyTV View Post
    Hey! I am still looking for a answer.
    I do not use eclipse; so, I have no idea what you need to do past adding all the source and header files to the project.

    Tim S.
    "...a computer is a stupid machine with the ability to do incredibly smart things, while computer programmers are smart people with the ability to do incredibly stupid things. They are,in short, a perfect match.." Bill Bryson

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. What does this error mean and how can I resolve it
    By Justinweq in forum C Programming
    Replies: 6
    Last Post: 11-22-2013, 05:20 PM
  2. Replies: 2
    Last Post: 01-10-2012, 08:49 PM
  3. How to resolve this error in c++?
    By hr1212s in forum C++ Programming
    Replies: 4
    Last Post: 05-11-2010, 02:47 AM
  4. need help to resolve the C# bug!!
    By ishwarverma in forum C# Programming
    Replies: 5
    Last Post: 09-08-2008, 08:04 PM
  5. Can't resolve strcat
    By Beowolf in forum C Programming
    Replies: 1
    Last Post: 09-11-2007, 06:47 PM

Tags for this Thread