I've recently started working on a chess engine, and am having trouble with a function to apply moves to the board. I have a structure type for the board state, and another to store moves. These are both in my header file below.
#ifndef DECLARATIONS_H
#define DECLARATIONS_H
#include <stdbool.h>
#define BOARD_SIZE 120
typedef struct move {
int startingSquare;
int endingSquare;
int promotionPiece;
} move;
typedef struct boardState {
int board[BOARD_SIZE];
bool whoseTurn;
int ply;
int threeMoveRuleCount;
int fiftyMoveRuleCount;
bool whiteCastleKingside;
bool whiteCastleQueenside;
bool blackCastleKingside;
bool blackCastleQueenside;
int enPassant;
float evaluation;
move previousMove;
} boardState;
boardState currentBoard;
#endif
Main.c calls the "Process Move" function from movegeneration.c. It passes one of the boardstate types and one of the move types:
#include <stdio.h>
#include <string.h>
#include "declarations.h"
int main () {
move firstMove;
firstMove.startingSquare = 35;
firstMove.endingSquare = 55;
firstMove.promotionPiece = 0;
printf("Value of firstMove.endingSquare: %d\n", firstMove.endingSquare);
printf("Value of firstMove.startingSquare: %d\n", firstMove.startingSquare);
printf("Value of firstMove.promotionPiece: %d\n", firstMove.promotionPiece);
processMove(currentBoard, firstMove);
return 0;
}
Below is movegeneration.c, which contains the function to process the move:
#include <stdio.h>
#include "declarations.h"
boardState processMove(boardState, move);
boardState processMove(boardState oldBoardState, move moveToApply) {
boardState newBoardState = oldBoardState;
printf("Value of moveToApply.endingSquare: %d\n", moveToApply.endingSquare);
printf("Value of moveToApply.startingSquare: %d\n", moveToApply.startingSquare);
printf("Value of moveToApply.promotionPiece: %d\n", moveToApply.promotionPiece);
return newBoardState;
}
And here's the program output:
Value of firstMove.endingSquare: 55
Value of firstMove.startingSquare: 35
Value of firstMove.promotionPiece: 0
Value of moveToApply.endingSquare: 0
Value of moveToApply.startingSquare: 55
Value of moveToApply.promotionPiece: 1996058613
This isn't all the code from the .c files, but it's everything relevant here. What makes this bizarre is that the values of the move change as soon as I call the function. When I put all the code into one large .c file and compile that way, the problem goes away, but I'm trying to keep the code separate to stay organized. This one has me completely stumped. I'd appreciate any help!
There's at least 2 problems here, causing undefined behaviour.
Firstly, there are multiple definitions of boardState currentBoard; . Remember that #include is a plain text replacement, so both of your c files end up with a definition of that object. See here for an in-depth explanation with examples.
If you want to have a global object accessible from multiple translation units then the header file should contain a declaration only (i.e. prepend extern to the current line), and exactly one of the .c files should contain the definition.
Secondly, in main() you call an undeclared function processMove. If you compile in standard mode then the compiler should generate an error message. This is likely the cause of your symptoms, and I would strongly recommend invoking your compiler in modern standard mode with a high diagnostic level, as it would have saved you a lot of time to find out about this problem sooner.
To fix this, the declaration boardState processMove(boardState, move); should be in declarations.h.
Related
At a rainy weekend, I was reading K. N. King's C Programming: A Modern Approach.
And at page 359, it says that βIt is possible that there are other functions in the same file as main, so long as they are not called from other files in the program.β
I do not know the reason and I try it like this:
// a.h
int sum(void);
int sub(void);
// a.c
#include <stdio.h>
#include "a.h"
#include "b.h"
int a = 0;
int b = 1;
int main(int argc, char const *argv[])
{
printf("sum = %d,\nsub = %d,\ndbl= %d\n", sum(), sub(), dbl() );
return 0;
}
int sum()
{
return ( a + b );
}
int sub()
{
return ( a - b );
}
// b.h
int dbl(void);
// b.c
#include "a.h"
#include "b.h"
int dbl()
{
return ( sum() + sub() );
}
Then I compile it with
gcc -a.exe a.c b.c
at cygwin. Then run a.exe as
./a.exe
Every thing goes well with the output "sum = 1, sub = -1, dbl = 0". So, who gets wrong, Mr K. N. King, or I ?
The cited part is program design advise.
There is nothing in the C language preventing you from putting a function definition anywhere in any linked file, as long as a function declaration is visible to the caller.
But it is very bad practice to have specific files call functions in what should be the top level of the application design. The key to good program design is to write autonomous code modules that only does their designated task and knows as little about the rest of the program as possible.
Having various parts of the application call other, non-related parts is sloppy, messy and leads to tight coupling. Apart from the program turning out a mess to read and maintain, tight coupling also means that bugs will escalate all over the program. Meaning that when you write a bug in one module, you will break completely non-related parts of the program.
To prevent such things, functions located in main should only be helper functions called by main itself, if such functions are needed. They should be declared as static functions to block other parts of the program from getting access to them.
In "a.h" include the following line:
extern int a;
extern int b;
Then retry your code and check the output.
I want to be able to modify a variable from one C file and see the changes of that variable on the other one
Here are my C files:
file1.c:
#include "myheader.h"
int
main( void )
{
printf("Variable %d\n", var);
}
file2.c:
#include "myheader.h"
int main(void){
int var = 1;
var = var + 1;
}
The header file looks like this:
extern int var;
Now, I want to run file2.c first and than when I run file1.c print the incremented value of var. Ideas?
I think I am doing everything like this answer, but can't make it work.
PS: Just started learning C.
Each of your "files".c has a main function and thus will compile into a separate executable.
So you can't have one executable increment a variable in its own address space and then have another executable see the change in someone else's address space - the other executable will have an own variable in its own address space. Unless you would use advanced inter process communication (but that is Lesson 42).
Scenario :
A C application created in Netbeans IDE with below two files:
some_function.c
#include <stdio.h>
int function_1(int a, int b){
printf("Entered Value is = %d & %d\n",a,b);
return 0;
}
newmain.c
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char** argv) {
//function_2(); //Error //function name not allowed
function_1();
function_1(1);
function_1(1,2);
return (EXIT_SUCCESS);
}
When learning the need of the header file in a C program, I tried the above application (as it is). It got compiled and gave the output as below
Entered Value is = 4200800 & 102
Entered Value is = 1 & 102
Entered Value is = 1 & 2
Question 1 : (I realize, in starting stage, to understand the process of the linker program is tough, hence i ask this question.) Is my assumption correct, that when linking, "the linker will check for the function name and not the arguments" in a condition the header file not used?
Regarding the header file usage, I came across this link and there it said as, we can include the C file itself using the #include. So, I used the below line in the file newmain.c
#include "some_function.c"
As expected it shown the below error
error: too few arguments to function 'function_1()'
error: too few arguments to function 'function_1(1)'
And also, I got the below (unexpected) error:
some_function.c:8: multiple definition of `function_1'
some_function.c:8: first defined here
Question 2: What error I did when including the 'c' file itself, as it gives the above said (unexpected) error?
You are probably using a pre-C99 dialect of C, which has "implicit function declarations". This means that functions without declarations are taken to have this kind of signature:
int function_1();
i.e. returning an int and accepting any number of arguments of any type. When you pass an argument list that is incompatible with your function definition, you invoke undefined behaviour at runtime.
Concerning the multiple definition errors, think of it. Each translation unit you include some_function.c will have its own definition of the function. It is as if you had written that definition in every other .c file. C doesn't allow multiple definitions in a program/library.
I (the questioner) post this answer for a quick understanding for some C programming starters. This answer inspired from the answers by #juanchopanza & #Sam Protsenko which are in this post.
Question 1 :Implicit function declarations in C
Question 2:
When using the below line
#include "some_function.c"
The result application will change like below after the preprocessor activity
some_function.c
#include <stdio.h>
int function_1(int a, int b){
printf("Entered Value is = %d & %d\n",a,b);
return 0;
}
newmain.c
#include <stdio.h>
#include <stdlib.h>
/*"#include "some_function.c"" replace begin by preprocessor*/
#include <stdio.h>
int function_1(int a, int b){
printf("Entered Value is = %d & %d\n",a,b);
return 0;
}
/*"#include "some_function.c"" replace end by preprocessor*/
int main(int argc, char** argv) {
//function_2(); //Error //function name not allowed
//function_1(); //Error
//function_1(1); //Error
function_1(1,2);
return (EXIT_SUCCESS);
}
Note : In the above two file, the function function_1 is there in two places
So now the below error is meaningful
some_function.c:8: multiple definition of `function_1'
some_function.c:8: first defined here
There is a header file named 'AAA.h'. In this header file we have define a structure called lrd, which looks like:
struct lrd
{
int tc;
char ptc[5];
char stc[5];
char ath[5];
int vc;
};
struct lrd lr;
This header file 'AAA.h' is included in two different files name 'BBB.c' and 'CCC.c'. We have assigned the values for structure variable lr in the 'BBB.c' file as following:
lr.tc=tc;
memcpy(lr.ptc,ptc,sizeof(ptc));
memcpy(lr.stc,stc,sizeof(stc));
memcpy(lr.ath,ath,sizeof(ath));
lr.vc=vc;
Above source variables take the value from database. And we use structure variable lr in the 'CCC.c' file. We are using structure lrd variable as follows:
char *ptc()
{
sprintf(str, "lr.ptc(%s)", lr.ptc);
trace(str);
return lr.ptc;
}
char *stc()
{
sprintf(str, "lr.stc(%s)", lr.stc);
trace(str);
return lr.stc;
}
Variable stc gives the wrong value in the 'CCC.c' file.
Please help me to figure it out.
See what benjarobin says. I am just showing you a small footprint
AAA.h
#ifndef _AAA_H
struct abc
{
int x;
char *y;
char *Z;
};
extern struct abc p;
extern void assign(void);
extern void display (void);
#endif
CCC.c
#include <stdio.h>
#include "AAA.h"
struct abc p; // Deceleration of p
void assign ()
{
p.x=20;
p.y="abcd";
p.Z="xyz0";
return;
}
BBB.c
#include <stdio.h>
#include "AAA.h"
void display (void)
{
printf("x = %d, y =%s, z=%s",p.x,p.y,p.Z);
}
DDD.c contains the main function.
#include <stdio.h>
#include "AAA.h"
void main ()
{
printf("\n\nAssigning Values\n\n");
assign ();
printf("\n\nIN BBB.c\n\n");
display ();
printf("\n\nIN MAIN\n\n");
printf("x = %d, y =%s, z=%s",p.x,p.y,p.Z);
}
output is
Assigning Values
IN BBB.c
x = 20, y =abcd, z=xyz0
IN MAIN
x = 20, y =abcd, z=xyz0
Your code shows:
memcpy(lr.ptc,ptc,sizeof(ptc));
memcpy(lr.stc,stc,sizeof(stc));
memcpy(lr.ath,ath,sizeof(ath));
It doesn't show the declarations of ptc, stc or ath. Since you are copying to lr.ptc etc, the operand of sizeof() should be lr.ptc etc, not the size of the source. Or, if you're being really careful, the minimum of the two sizes.
You could/should debug this with:
printf("%d (%s)(%s)(%s) %d\n", lr.tc, lr.ptc, lr.stc, lr.ath, lr.vc);
immediately after the assignments. If that shows the wrong value, then you know the problem is in the assignments. If that shows the correct values, then you can start looking for stray pointers and other such ghastly problems.
There's no proof that this is the problem because you've not produced an SSCCE (Short, Self-Contained, Correct Example). Specifically, you've only produced fragments of code, not an integrated set of three source files (though we can infer the header from the information given). And without the code that actually demonstrates the problem (all of it, including definitions for all the variables and functions β but not including any superfluous material), we can only speculate.
External variable should be avoid, but if you still want to use a global variable, you shall do these :
Declare the variable in a .c file
struct lrd lr;
Add the external definition in the .h (AAA.h)
external struct lrd lr;
For example: If I have two .h files
process1.h and process2.h
and they contain two function with different output variables.
process1.h:
function(int var)
{
return 2*var;
}
process2.h:
function(int var)
{
return 10*var;
}
Can this be done in main.c:
int main()
{
int a = 2;
#include "process1.h"
printf("%d",function(a)); //output is 4
EXCLUDE #INCLUDE "process1.h" ????? <----can this be done in any way??
#include "process2.h"
printf("%d",function(a)); //output is 20
}
No, you cannot "un-include" a file. Think of all the preprocessor directives (lines starting with #) as happening before the actual C compiler even sees the source file. They just operate on the text of the file, and the preprocessor could be implemented as a separate step that just feeds new text into the actual compiler.
The best way to modify the actions of an include depending on the caller is to use further macros inside the included files, that you can #define before including them.
Still, your overall syntax is off, you can't (typically) nest functions in C.
No, and you should not try to write a program with two functions of the same name.
In the special case that the functions are actually defined in the header file (instead of just prototypes), you can do this:
#define function function_file1
#include "file1.h"
#undef function
#define function function_file2
#include "file2.h"
#undef function
int
main (void)
{
int a = 2;
printf ("%d\n", function_file1 (a));
printf ("%d\n", function_file2 (a));
}
BUT if you rename a function prototype then you haven't actually renamed the real function, so you'll get undefined symbol error when you link.
In any case, if you have two functions defined with the same name then it won't link anyway, not matter what else you do in the sources. (In C++, it is sometimes possible to define two things with the same name, but the One-Definition-Rule means the linker is allowed to assume they are both the same thing really and just pick one.)
This is why libraries are supposed to use names that won't be used elsewhere - usually by adding a common prefix to all symbol names (e.g. my_unique_lib_initialize()).
Why not use array of function pointers. Sure you need to initialize it at the start but I think it probably solves what you want to do.
int process1_function(int var);
int process2_function(int var);
int main(void)
{
int i, a = 10;
int (* functions[2])(int);
functions[0] = process1_function;
functions[1] = process2_function;
for(i=0; i < 2; i++)
{
printf("%d", (functions[i])(a));
}
return 0;
}
If you do not need to dynamically change which function you're going to call you can also just prefix the functions:
int process1_function(int var);
int process2_function(int var);
int main(void)
{
printf("%d",process1_function(a));
printf("%d",process2_function(a));
return 0;
}