What is wrong with using extern in C like that? - c

I've already searched something abou this but I've still don't understand it..
file1.h
extern int *game_array[5];
Player.c
#include "file1.h"
void *delete_player(player_struct *player)
{
... //some code
game_array[5] = 5; //undefined reference to `game_array`
... //some code
}
When I don't use extern it "work's fine" = I can build it withou errors, but the program's not finished ..
I suppose the using extern is fine but something is wrong ..
I want to use this game_array ... array of games on server from all my .c source files, there's only one instance of this array in my aplication.

You need to define game_array in one of your .c files, and compile/link that file into your executable.
The definition will look like this:
int *game_array[5];
What your file1.h is saying is basically "There exists a variable called game_array somewhere in my project, and it has such-and-such type". However, the variable doesn't actually exist until you've defined it somewhere (typically, in a .c file).

The extern keyword basically means that the compiler should not complain about the symbol, even if it's not defined, because it will be available at link-time.
So if it's not defined at link-time, you'll obviously have errors.
You need to provide an implementation in one of your C file:
Something like:
#include "file1.h"
int * game_array[ 5 ];
void * delete_player( player_struct * player)
{
...

Writing extern int *game_array[5]; means that somewhere, in some file, there's an actual definition for game-array -- i.e., a declaration without the extern. You're failing to provide that, so the linker complains that the actual variable doesn't exist anywhere.

Related

#include "another_source.c", use inline function( ) there, then does the function( ) become inline as well?

Let's say I have two files named "AA.c", "BB.c"
/* in AA.c */
inline void AA(void) __attribute__((always_inline));
void AA()
{
/* do something */
}
and then
/* in BB.c */
#include "AA.c"
extern void funcAA(void);
int main(void)
{
funcAA();
return 0;
}
does funcAA( ) also become inline???
no matter the answer is yes or no, could you explain some more about the under the hood??
including a .c file is equivalent of copying and pasting the file contents directly in the file which includes that, exactly like if the function was directly defined in the including file.
You can see what the compiler is going to compile by trying to compile your file with -E flag (preprocessor output). You'll see your function pasted-in.
So it will be inline just because of the inline keyword, and forced with the always_inline attribute even if the compiler would have refused to inline it because of function size for instance.
Word of advice: know what you're doing when including a .c file from another one. Some build systems/makefiles just scan the directories looking for files called *.c so they can compile them separately. Putting a possibly non-compiling C file there can make the build fail, and if it builds, you could have duplicate symbols when linking. Just don't do this.
If you want to do this, put your function in a .h file and declare it static so it won't fail the link if included in many .c files (each function will be seen as different)

Nsight Eclipse 5.5 identifier is undefined

In a project with many .cu files and a .h file, I have some constants defined in my main.cu like this (shown just one as example):
__device__ __constant__ unsigned int x[1];
#include "second.cu"
... some code...
In the file second.cu I am trying to use that constant, like this:
cudaMemcpyToSymbol(x, y, sizeof(xx));
But Eclipse is giving me the error: identifier "x" is undefined.
I noticed that #includes in my main.cu, like the header.h, I need to specifically add in all the .cu files again. Which produced some redefinition problems that I solved using #pragma once.
I am new to Eclipse in general, found some complains about the CDT regarding include files not being indexed. I tried the Index Rebuild/Update/Freshen/Re-resolve method that worked for some in this regard, but with no luck with my problems.
Also, tried disabling the 'heuristic resolution of includes' in Properties -> Indexer. I thought I got it for a few moments but then the error showed up again.
Any ideas to solve this problem?
This is a C/C++ problem and have nothing to do with CUDA.
Generally people don't include source files like .cu .cpp .c. Only header files like .h should be included.
If you have a global variable int x need to be referenced in many source files. You could define it in one souce file as
// main.cu
int x;
...
declare it in a header file as
// main.h
extern int x;
...
and include this header file in all the source files you will reference that variable as
// second.cu
#include "main.h"
void foo() {
int local=x;
}
...
and
// third.cu
#include "main.h"
void bar() {
int private=x;
}
...

Header File being included twice

I am relatively new to C (as I don't want to use C++, or at least just yet) and I'm not sure how to fix my include error I am having.
I have a header file containing the constant value of 1000 and is called Test.
const int Test = 1000;
I have this file included in 2 files - Myfile.c and Myfile2.c each including the file as such:
#include "MyHeader.h"
My project will not build/compile and as I have found out it is including the header twice which is not allowed as I am declaring my variable "Test" twice. Upon research I found this on Wikipedia: http://bit.ly/10wPraP
I used this "Include Guard"
Example:
#ifndef MY_HEADER
#define MY_HEADER
const int Test = 1000;
#endif
and I have also tried the pre-processor(?) command pragma once.
#pragma once
However, my program still will not build. I now get error saying that the varibale "Test" is already defined in MyFile.obj.
I thought this might be a Visual Studio-ism as I am using that but both my 2010 Express C++ and VS2003 Professional wont build this. I have tried cleaning the project within Visual Studio and I am not sure what else to do.
Am I being very silly and missing something obvious here and that is why it isn't work?
I am used to C# and "using" with namespaces rather than includes. May my setting on VS to only compile C code be effecting this?
Include guards have nothing to do with it. You need to separate the declaration from the definition and have only one definition (this is called the "one definition rule", ODR):
header.h:
extern const int n;
one source file:
#include "header.h"
const int n = 1000;
all other source files:
#include "header.h"
Useful Reference:
Wikipedia on the extern keyword: https://en.wikipedia.org/wiki/External_variable
Wikipedia on the One Definition Rule: https://en.wikipedia.org/wiki/One_Definition_Rule
The problem is with the way that header files are processed when you #include them: Header files are literally copied and pasted into the body of your C files. This means that Myfile.c and Myfile2.c both have their own declarations of an int named Test - essentially creating two different versions of the one variable. The linker then complains about having two different variables with the same name.
The solution is to put the const int Test = 1000; in one of your C files, and to add extern const int Test; to MyHeader.h. This way, the variable is declared only once, and all files are aware of the one variable because the extern directive tells them that another file has the variable Test they are looking for.
MyHeader.h
extern const int Test;
Myfile.c (for instance)
#include "MyHeader.h"
...
const int Test = 1000;
Myfile2.c
#include "MyHeader.h"
...
<use Test>
This is correct. You have two source files that are defining Test. You should only define this once. Since header files get included all over the place, they should generally only declare variables, not define them. e.g.
header:
const int Test;
Exactly one c file:
const int Test = 1000;
Define that variable in any one of the .c file and declare that as extern in the header files.
#ifndef MY_HEADER
#define MY_HEADER
extern const int Test;
#endif
In Myfile.c define the variable
const int Test = 1000;

how to define a variable in one file and use it in another one

The question may be very basic but I am not getting clue anyways ...
I have two files ...
and I am mentioning what I want to do .
file 1
...
j = data->alloc_len;
...
file 2
...
for(i=0;i<j;i++)
...
Its clear from above I want to assign value to a variable in one file and want to use that value in other file.
I tried #include "file1.c" in file2.c but it is giving lot of re-declaration errors.
I tried creating a seperate header file which only have one line int j and then included it in both files using extern but no benefit again.Although I think header files are meant for where i can create and assign a value to a variable in one file and then this value can be propogated to all other files by including this one.
May be I am wrong but I need it soon so please help me ...Thnx in advance.
Limitation -
The value can be assigned only through file1.c because data structure is declared and defined here only.I can not provide a value to variable j in a header file .
EDIT :
Although I mentioned but I think I could not clear my question.I have tried using it header files.
For debugging purpose I tried this ..
sample.h
extern int j;
file1.c
#include "sample.h"
int j=245;
file2.c
#include "sample.h"
printf("%d",j);
but its getting error .
Error I am getting is :
Couldn't open module sample.so, tried:
sample.so: cannot open shared object file: No such file or directory
./sample.so.so: cannot open shared object file: No such file or directory
/usr/local/lib/sendip/sample.so.so:
cannot open shared object file: No such file or
directory
/usr/local/lib/sendip/sample.so: undefined symbol: j
*none of the file contains main function actually *
Actually it is a very large project and I am using Makefile and all files will be linked at run time.
In short,the execution could be understood as there is a main.c file which contains main which in turns call file1.c and which in turn calls file2.c
About descriptive names I would say they are just for showing here otherwise I am already using descriptive name.
You could put this in a header file:
extern int j;
and only declare the "real" j in file1.c. If file2.c includes that header, then it can use variable j.
But, use descriptive variable names a the very least for globals. And you should avoid globals as much as you can, they are a liability in the long term, IMO.
(You could consider something like making a function in file1.c that returns that value. This has the advantage of assuring that j is controlled in file1.c, and only read in other places, limiting the complexity of understanding who "owns" that variable.)
like this
in the c file you define the variable say file1.c you write
int j;
...
j = data->alloc_len;
a header for your file1.h would contain
extern int j;
this header you include in file2.c
#include "file1.h"
but i would suggest using a more descriptive variable name.
#include "file1.c" is almost never the correct solution to a problem. Invariable you want to be declaring things in header files and then defining them in just a single source file.
file1.h
extern int j;
file1.c
#include "file1.h"
j = data->alloc_len
file2.c
#include "file1.h"
if (j>0)
...
Having said all of this, I would strongly council you to pass values as parameters rather than use global state. Global state is evil. Avoid it like the plague.

How to prevent multiple definitions in C?

I'm a C newbie and I was just trying to write a console application with Code::Blocks. Here's the (simplified) code:
main.c:
#include <stdio.h>
#include <stdlib.h>
#include "test.c" // include not necessary for error in Code::Blocks
int main()
{
//t = test(); // calling of method also not necessary
return 0;
}
test.c:
void test() {}
When I try to build this program, it gives the following errors:
*path*\test.c|1|multiple definition of `_ test'|
obj\Debug\main.o:*path*\test.c|1|first defined here|
There is no way that I'm multiply defining test (although I don't know where the underscore is coming from) and it seems highly unlikely that the definition is somehow included twice. This is all the code there is.
I've ruled out that this error is due to some naming conflict with other functions or files being called test or test.c. Note that the multiple and the first definition are on the same line in the same file.
Does anyone know what is causing this and what I can do about it? Thanks!
You actually compile the source code of test.c twice:
The first time when compiling test.c itself,
The second time when compiling main.c which includes all the test.c source.
What you need in your main.c in order to use the test() function is a simple declaration, not its definition. This is achieved by including a test.h header file which contains something like:
void test(void);
This informs the compiler that such a function with input parameters and return type exists. What this function does ( everything inside { and } ) is left in your test.c file.
In main.c, replace #include "test.c" by #include "test.h".
A last point: with your programs being more complex, you will be faced to situations when header files may be included several times. To prevent this, header sources are sometimes enclosed by specific macro definitions, like:
#ifndef TEST_H_INCLUDED
#define TEST_H_INCLUDED
void test(void);
#endif
The underscore is put there by the compiler and used by the linker. The basic path is:
main.c
test.h ---> [compiler] ---> main.o --+
|
test.c ---> [compiler] ---> test.o --+--> [linker] ---> main.exe
So, your main program should include the header file for the test module which should consist only of declarations, such as the function prototype:
void test(void);
This lets the compiler know that it exists when main.c is being compiled but the actual code is in test.c, then test.o.
It's the linking phase that joins together the two modules.
By including test.c into main.c, you're defining the test() function in main.o. Presumably, you're then linking main.o and test.o, both of which contain the function test().
You shouldn't include other source files (*.c) in .c files. I think you want to have a header (.h) file with the DECLARATION of test function, and have it's DEFINITION in a separate .c file.
The error is caused by multiple definitions of the test function (one in test.c and other in main.c)
I had similar problem and i solved it following way.
Solve as follows:
Function prototype declarations and global variable should be in test.h file and you can not initialize global variable in header file.
Function definition and use of global variable in test.c file
if you initialize global variables in header it will have following error
multiple definition of `_ test'|
obj\Debug\main.o:path\test.c|1|first defined here|
Just declarations of global variables in Header file no initialization should work.
Hope it helps
Cheers
Including the implementation file (test.c) causes it to be prepended to your main.c and complied there and then again separately. So, the function test has two definitions -- one in the object code of main.c and once in that of test.c, which gives you a ODR violation. You need to create a header file containing the declaration of test and include it in main.c:
/* test.h */
#ifndef TEST_H
#define TEST_H
void test(); /* declaration */
#endif /* TEST_H */
If you have added test.c to your Code::Blocks project, the definition will be seen twice - once via the #include and once by the linker. You need to:
remove the #include "test.c"
create a file test.h which contains the declaration:
void test();
include the file test.h in main.c
If you're using Visual Studio you could also do "#pragma once" at the top of the headerfile to achieve the same thing as the "#ifndef ..."-wrapping. Some other compilers probably support it as well ..
.. However, don't do this :D Stick with the #ifndef-wrapping to achieve cross-compiler compatibility. I just wanted to let you know that you could also do #pragma once, since you'll probably meet this statement quite a bit when reading other peoples code.
Good luck with it
Ages after this I found another problem that causes the same error and did not find the answer anywhere. I thought to put it here for reference to other people experiencing the same problem.
I defined a function in a header file and it kept throwing this error. (I know it is not the right way, but I thought I would quickly test it that way.)
The solution was to ONLY put a declaration in the header file and the definition in the cpp file.
The reason is that header files are not compiled, they only provide definitions.

Resources