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: Tim Roberts on 22 Dec 2009 23:04 "Leslie Milburn" <CDB4W(a)NOSPAM.bigpond.com> wrote: > >"Tim Roberts" <timr(a)probo.com> wrote: > >> Although I agree that his current implementation has an almost unlimited >> number of problems, the big issue he's facing is that he's writing for an >> embedded processor. On many embedded processors, such as the PIC series >> that he's targeting, the stack is your enemy. It can be very expensive to >> use parameters and stack local variables, so you end up using globals more >> than you ordinarily would. > >Then the static keyword is your friend as it is allocated the once and it >can then be passed as a parameter as required. IMO this is much cleaner !! I don't think you appreciate the problem. You've been working for too long in systems with infinite memory and infinitely fast processors. 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. -- Tim Roberts, timr(a)probo.com Providenza & Boekelheide, Inc.
From: David Wilkinson on 23 Dec 2009 06:29 Robby wrote: > Hello Ron, one more thing, > > I have tried your suggestion but it compiles with an error. Here is the code: > > > ===============KERNEL.h > enum enumKM{KM_QUIT = 0, KM_CREATE = 1, KM_RECUR = 2}; > extern long MQ[10]; > > ===============KERNEL.c > #include <stdio.h> > #include "KERNEL.h" > #include "API.h" > > 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) > { > long h=1; > MQ[1]= h; > } > ========================== > > The following error is reported at compile time: > > 1>API.obj : error LNK2001: unresolved external symbol _MQ > > And I did include KERNEL.h in API.c as you indicated ????? MQ[10] is declared but not defined. If it is declared in KERNEL.h, it should be defined in KERNEL.c. -- David Wilkinson Visual C++ MVP
From: David Wilkinson on 23 Dec 2009 06:32 Robby wrote: > Ron, > > I don't think I would create a header file just dedicated to global externs. > Becuase, then why not dedicate a header file for more than just extersn... > why not just for externs and #defines and where do you draw the line as to > what else we can put in there. So I would be mre comfortable with a KERNEL.h > and put the exters, #defines and some struct declarations and include > KERNEL.h in every .c file. > > So getting back to your suggestion, I guess that you meant it to be coded > this way: > > ===============KERNEL.h > enum enumKM{KM_QUIT = 0, KM_CREATE = 1, KM_RECUR = 2}; > extern long MQ[10]; > > ===============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) > { > long h=1; > MQ[1]= h; > } > ========================== > > Now the above compiles without errors or warnings. It does? You have extern long MQ[10]; // declaration long MQ[2] = {1,2]; // definition -- David Wilkinson Visual C++ MVP
From: Ron Francis on 23 Dec 2009 07:54 "Robby" <Robby(a)discussions.microsoft.com> wrote in message news:C81EE069-E512-4220-A3BF-3CB6B2EFB239(a)microsoft.com... > Ron, > > I don't think I would create a header file just dedicated to global externs. > Becuase, then why not dedicate a header file for more than just extersn... > why not just for externs and #defines and where do you draw the line as to > what else we can put in there. So I would be mre comfortable with a KERNEL.h > and put the exters, #defines and some struct declarations and include > KERNEL.h in every .c file. > > So getting back to your suggestion, I guess that you meant it to be coded > this way: > > ===============KERNEL.h > enum enumKM{KM_QUIT = 0, KM_CREATE = 1, KM_RECUR = 2}; > extern long MQ[10]; > > ===============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) > { > long h=1; > MQ[1]= h; > } > ========================== > > Now the above compiles without errors or warnings. > > Thanks all for your replies. Very appreciated Robby, 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. 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. 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. I think it is (or was) common to prefix a lowercase "g" to a variable to denote that it is global. Something like g_MQ. 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. Ron.
From: David Wilkinson on 23 Dec 2009 08:51
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; } If you had pasted this code into a test console project (as I did), you would immediately have found two compiler errors. After correcting the errors, you would find that if you commented out the definition above (leaving only the declaration) then you would get a linker error. Even if it does not help you to figure out the problem yourself, putting all the code in a single file greatly increases the chance that a reader will paste your code into a test project and figure it out for you. I always have such a test project available for precisely this purpose. -- David Wilkinson Visual C++ MVP |