|
|
|||||||||
|
|||||||||
| |||||||||
|
|
|
| |||||||||
![]() |
|
|
«
Previous Thread
|
Next Thread
»
|
Thread Tools | Search this Thread | Rate Thread | Display Modes |
|
|
|
Get inside! Sample the range of functionality easily built with JMSL Library for Time Series Data Analysis, Heat Maps, Portfolio Optimization, Monte Carlo Simulation, Stock Price Charting and more. Download Now! |
|
#1
|
||||
|
||||
|
undefined reference using a global variable in a function
The answer to this is probably simple, but im not used to programming in C using gcc. Here is the error :
In function `print_statistics': /home/1nfamus/Programs/hping2-rc2/statistics.c:42: undefined reference to `averageID' relid.o: In function `relativize_id': /home/1nfamus/Programs/hping2-rc2/relid.c:43: undefined reference to `averageID'collect2: ld returned 1 exit status make: *** [hping2] Error 1 averageID is a globabl variable i declared in the "global.h" included in both of the above .c files. What exactly does undefined reference mean? |
|
#2
|
||||
|
||||
|
ld is the GNU linker. averageID is declared in global.h, but in which .c source file is it actually defined?
|
|
#3
|
||||
|
||||
|
edit: ahh nevermind; i didnt realize i had to initialize averageID in main. got my revamped hping working perfect now!
Last edited by infamous41md : May 5th, 2003 at 12:21 PM. |
|
#4
|
|||
|
|||
|
Those are just references. Where is it defined?
|
|
#5
|
||||
|
||||
|
Tested it ...
When in doubt, code and test it, I always say.
Since I always declare a global variable as an extern in a header file, I assumed that either you had done so as well or, if not, that gcc had assumed it to be an extern. To verify what would happen if the extern keyword were left out of the header, I did a quick two-module test project: mod1.c Code:
// module 1
#include "global.h"
//int g_int = 0;
int main(void)
{
g_int = 42;
fn1();
return 0;
}
mod2.c Code:
// module 2
#include <stdio.h>
#include "global.h"
void fn1(void)
{
printf("g_int = %d\n",g_int);
}
global.h Code:
#ifndef _GLOBAL_H_ #define _GLOBAL_H_ int g_int; void fn1(void); #endif Command Line: Code:
C:\dcw\PROJECTS\TEST>gcc mod1.c mod2.c C:\dcw\PROJECTS\TEST>a g_int = 42 C:\dcw\PROJECTS\TEST> Normally, I would have expected to get a link error for multiple definitions of the same variable, so I was surprised by the apparently clean make. Then I expected each module to have its own copy of g_int so that the change in mod1 would not be seen by mod2. Again I was wrong. I just ran nm on a.exe and there is only one instance of g_int. Personally, I find gcc to be a bit too accommodating here. Of course, it might just be that my gcc is configured to be less strict than I think it should be (I haven't changed it, so it's set to the installed default -- MinGW installed by Dev-C++ beta 5). Last edited by dwise1_aol : May 5th, 2003 at 01:54 PM. |
|
#6
|
||||
|
||||
|
yes i declared it as an extern int in the globals file.
so when u assigned it in main() that was taken to be the "defining" of it? ... this stuff is kind of confusing to me, i've never used the extern keyword before, i had to look it up to even know what it meant. this was the C source for hping2. i was trying to modify a couple things in it, and i came to realize how different C is compared to C++. the format and flow of the program is so hard for me to understand. i learned how to do pretty much everything from an object oriented perspective so following along in these progs is . i want to rewrite it into an oo version![]() |
|
#7
|
||||
|
||||
|
Quote:
No, the definition in my test (not using "extern") was when the header file got included. What the #include directive does is to insert the file directly into the source file at that point. You could also use it to insert executable code into the source file -- rarely used for that, but it can be done. More properly, mod1.c and global.h should have read: Code:
#ifndef _GLOBAL_H_
#define _GLOBAL_H_
extern int g_int; /* just declared here; no memory space allocated for it yet */
void fn1(void);
#endif
--------------------------
// module 1
#include "global.h"
int g_int = 0; /* now this is where it actually gets defined */
int main(void)
{
g_int = 42;
fn1();
return 0;
}
Quote:
C is not really that different from C++ except for the overall approach that OOP offers. I remember that one of the major hurdles for C programmers to get over was switching over to an OO approach. Similarly, I saw some programmers really struggle learning the Windows approach of doing everything inside of event handlers. Encountering a different way of doing something is rarely easy. However, extern is also needed in C++ when you define a global object in one module that is needed in another module. Though you probably have not encountered it because a common practice is to access such objects through pointers that are passed and returned through functions and methods. |
|
#8
|
|||
|
|||
|
Ummm.......
I think you have it the wrong way round. I think you are just creating two variables with the same name. Try using g_int in another file that does not include global.h Try this method globals.h (include this header file ONLY in the main file of your app) In this example the main app file is main.c globals.h Code:
#ifndef _GLOBAL_H_//beware of using variables and defines with leading underscores as this is not ANSI compliant (they are reserved) #define _GLOBAL_H_ int g_int=0; //declare and init here void fn1(void); #endif in the main.c Code:
#include globals.h extern int g_int;//can not init here in any other file in the project just declare it as extern int g_int;//can not be init here
__________________
The essence of Christianity is told us in the Garden of Eden history. The fruit that was forbidden was on the Tree of Knowledge. The subtext is, All the suffering you have is because you wanted to find out what was going on. You could be in the Garden of Eden if you had just kept your f***ing mouth shut and hadn't asked any questions. Frank Zappa |
|
#9
|
|||
|
|||
|
That's backwards. dwise had it right. You want the header file to be included anywhere that something in it is needed. The definition should only be in the module that owns the item.
|
|
#10
|
|||
|
|||
|
dwise1_aol uses the 'common' method of using extern. This is not allowed under ANSI C. A stricter declaration is required (as per my example). Both will work however.
But why declare the global (g_int) in a header and then again in a file that includes the globals header? (Comment out the #include and see if you can still use g_int, if so why use that method?) I like to declare any global variables in one header file and externally define _only_ those I need in any source file in the project (and not have to include them all as per dwise1_aol's method). |
|
#11
|
|||
|
|||
|
No, dwise's method is correct. Your method is doing effectively the same thing, but it isn't as clear nor as standard. In dwise's example, he is defining the variable once in the .c file. He is then providing a way for other files to include its declaration. Your method also defines the variable once, and provides a way to include its declaration. For this simple example both methods are equivalent. Where I believe your method becomes unmanageable is when there is a need to declare structures, types, functions, and even #defines. With your method you would have to put each of these into every file that needs to use them, including the one that "owns" them. In dwise's method, they would just be in the .h file and each file would just need to include that file. In general, I feel it is typically best to not include definitions in header files.
|
|
#12
|
||||
|
||||
|
Just to clarify what I did, I tried an experiment in which I defined a global variable in the header just to see if I could duplicate what infamous was seeing.
I don't normally do that. Normally, I have a header for each code module which contains only: 1. #defines that are needed by any other modules in the program. 2. type definitions that will be needed by other modules. 3. extern variable declarations that will be needed by other modules. 4. function prototypes that will be needed by other modules. Normally, I never put a variable definition in a header file and I never put code in a header file (notable exception: an inline function in a class). And if something is not needed outside of the module, it doesn't go into the header file. Rather than collect the all the type definitions or the externs of all the global variables into a single header, I will usually place them in the header for the module that defines them. That way, a module can be more selective about what it pulls in. Last edited by dwise1_aol : May 8th, 2003 at 10:09 AM. |
|
#13
|
|||
|
|||
|
That is exactly what I was talking about doing. Everything that another module needs to know about the module of interest should be in the header. Perhaps I should have been more clear that I was referring to the post where dwise1_aol said
Quote:
|
|
#14
|