Prev: Reference to an undefined assignment operator of a base class in a derived class.
Next: How to convert a Borland C++ App to Visual Studio App
From: Barry Schwarz on 23 Dec 2009 09:41 On Wed, 23 Dec 2009 23:24:02 +1030, "Ron Francis" <ronfrancis(a)adam.com.au> wrote: snip >Please excuse me being obvious, but I'm not sure how much you understand. >Yes, you still have to define MQ and it would make sense to do that in your KERNAL.c >When you use 'extern', you are just telling the compiler that the variable is defined elsewhere and >because the compiler couldn't find a definition anywhere, you got the error.. > >If you want to use MQ in another file, you have to tell it that it is defined somewhere else, so >normally you would normally put >extern long MQ [10]; >near the beginning of the file. >Anyone reading the file can easily see that MQ is defined somewhere else. >If you 'hide' the declaration in KERNAL.h then someone would have to search for it. > >You can think of a header file as just being an addition to a *.c file that it is embedded in. >That is, you can read it as all one file. > >That is why David said ... >"You have >extern long MQ[10]; // declaration >long MQ[2] = {1,2]; // definition" >Because you have included KERNAL.h within KERNAL.c, it becomes one file and so you have made a >declaration and definition within the same file. >I'm surprised that it compiles but I don't know much about how compilers work. The issue being raised was not that the declaration and definition were in the same translation unit but that they were inconsistent within that unit, along with the obvious typographical error. -- Remove del for email
From: Igor Tandetnik on 23 Dec 2009 11:24 Pavel A. <pavel_a(a)12fastmail34.fm> wrote: > All this just confirms the old Russian proverb - that one user can > ask a question that 100 admins won't answer. First recorded in Italy in 17th century, apparently: http://www.encyclopedia.com/doc/1O90-FLSskqstnsthtwsmncnntnswr.html -- With best wishes, Igor Tandetnik With sufficient thrust, pigs fly just fine. However, this is not necessarily a good idea. It is hard to be sure where they are going to land, and it could be dangerous sitting under them as they fly overhead. -- RFC 1925
From: Robby on 23 Dec 2009 13:01 "David Wilkinson" wrote: > The point under discussion could have been illustrated by the single file > complete program > > extern long MQ[10]; // declaration > > long MQ[2] = {1,2]; // definition > > int main() > { > long n = MQ[0]; > return 0; > } "David Wilkinson" wrote: > David Wilkinson wrote: > > It does? > > > > You have > > > > extern long MQ[10]; // declaration > > > > long MQ[2] = {1,2]; // definition > > Robby: > > Actually, I now see that in the above (which I copied from your post), there is > an obvious typo in the definition, so the code most certainly will not compile. > > I realize that your real code is too long to post, but there is a real danger in > just typing code into a post, because you will inevitably introduce errors that > are unrelated to the question you are asking. > > The point under discussion could have been illustrated by the single file > complete program > > extern long MQ[10]; // declaration > > long MQ[2] = {1,2]; // definition > > int main() > { > long n = MQ[0]; > return 0; > } Yes David, I understand your point, but the original question concerned on how to declare global variables with multiple files, so I figured to post something as realistic as possible to the core of my question. Don't forget I still am a little shaky with the right way of using the #includes since all this time I was used to including headers just once in a particular .c file. About the typo's ... I am rushing all the time to try to keep up with all the propositions. And I really don't know how I do these typo's... I always try them first in VC++ and then I paste them as they are. My fault I know! Sorry for the typo, I now have tested it, and this is what I meant: > ===============KERNEL.h enum enumKM{KM_QUIT = 0, KM_CREATE = 1, KM_RECUR = 2}; extern long MQ[2]; ===============KERNEL.c #include <stdio.h> #include "KERNEL.h" #include "API.h" long MQ[2] = {1,2}; int main() { API_InsertMessage(KM_QUIT); return 0; } ===============API.h void API_InsertMessage(enum enumKM m); ===============API.c #include "API.h" #include "KERNEL.h" void API_InsertMessage(enum enumKM m) {MQ[1]= 1;} ========================== I just don't see how we are not supposed to declare extern's in our header file. I know theres a dispute going on here, I didn't read it til the to see how it ends up, but how can we say that extern int x; is code ????? I include this in many .c files and I don't get any variable duplication errors ??? Thanks for your reply! Rob
From: Robby on 23 Dec 2009 13:56 "Ron Francis" wrote: > Please excuse me being obvious, but I'm not sure how much you understand. Not much... obviously! > Yes, you still have to define MQ and it would make sense to do that in your KERNAL.c > When you use 'extern', you are just telling the compiler that the variable is defined elsewhere and > because the compiler couldn't find a definition anywhere, you got the error.. > If you want to use MQ in another file, you have to tell it that it is defined somewhere else, so normally you would normally put > extern long MQ [10]; > near the beginning of the file. Anyone reading the file can easily see that MQ is defined somewhere else. Understood. > If you 'hide' the declaration in KERNAL.h then someone would have to search for > it. You can think of a header file as just being an addition to a *.c file that it is > embedded in. > That is, you can read it as all one file. > > That is why David said ... > "You have > extern long MQ[10]; // declaration > long MQ[2] = {1,2]; // definition" > Because you have included KERNAL.h within KERNAL.c, it becomes one file and so you have made a > declaration and definition within the same file. > I'm surprised that it compiles but I don't know much about how compilers work. Yes, but if you try to do this: ==============Kernel.c #include <stdio.h> #include "API.h" extern long MQ[2]; long MQ[2] = {1,2}; int main() { return 0; } ================= It should compile without errors! My point is that we should be able to declare a variable and then define it down stream of our program... so what is the difference if we declare it in a header and include that header in a ..c file and define that variable then. In other words, what is the harm if we do this: ===============KERNEL.h extern long MQ[2]; // *** DECLARED *** ===============KERNEL.c #include <stdio.h> #include "KERNEL.h" #include "API.h" long MQ[2] = {1,2}; // *** DEFINED *** int main() {return 0; } ================== > Getting back to hiding the declaration, in my case, I put all my externs in their >own header file for readability. Someone looking through a file wouldn't see an >extern keyword, but I thought the next best thing would be to see extern.h and >hopefully assume that it would contain declarations. I like this proposition more and more to declare all the externs in a seperate header file and define each extern in exactlty one .c file and include the extern header file in every other .c file as required. This makes the best sence since when a user looks at a .c file and sees the inclusion of the extern.h file, he knows that this .c file uses global variables. But now, we have Leslie that discourages the use of extern in a header file... if I am mistaken... or I think this was resolved as allowable to do so. I don't know anymore... too many ways of doing a simple task. Your proposition seems to compile in VC++ and MPLAB without errors or warnings. So I like your proposition and I am sticking to it. :-) > If I had lots of #defines I would probably have a separate defines.h file, but I don't know that this is common practice. Perhaps this too could be good... but I can't say for sure! > I know very little compared to many here, so I hope I haven't led you astray. > I'm sure I'll be corrected if I said something wrong. I know the least compared to all of them. However, I do appreciate their help! :-) Thankyou Ron for your help. Thanks to all your feedback and happy holidays to all! Regards Rob
From: sasha on 23 Dec 2009 15:31
Tim Roberts wrote: > Parameters are part of the problem, as I said in my post. Sure, the code > is architecturally more "pure" by using parameters, but when your stack is > only 16 bytes long and it costs a dozen cycles to change stacks, you have > to make different choices. Then the parameters are passed by a pointer to a list of parameters stored elsewhere (like IBM System 360 did). It's up to a compiler to figure out how to do that :) |