I have two files fsm_right.c and fsm_left.c
in my main program, before any other header files, I have this
#define FSM 1
#ifdef FSM #ifdef FMSLEFT // note: currently undefined include "fsm_left.c" #else include "fsm_right.c" #endif #endif
the next line is
unsigned char author= "whatever";
The compiler spits up on the assignment line, with a C129 missing ';' before <string>
So I figured, something in fsm_right was incorrect. To test this, I commented out the include "fsm_right.c" (and this same thing happens with the <fsm_right.c> syntax. The program compiles without a problem. So I figured the problem was in fsm_right.c I edited fms_right.c and deleted EVERYTHING in it, so it is just a blank file.
And it *STILL* has the error. This is version 7.5 by the way. K&RC say that the include statement is replaced by the contents of the file.
What in the world is going on here? With the include commented out //include ..... it compiles fine. With the include NOT commented out, it gives the error WHETHER OR NOT there is anything in the body of the included file.
This makes no sense. Is there a bug in the pre-processor? environment is windows XP running Silabs IDE with the Keil 7.5 as the compiler. I've seen this before, could not figure it out and went a different direction, but now I need to have it this way.
The project consists of a main file, and a second C file with some constants and structures. I compile them seperately and link them. Now I need to build two new configurations, to be controlled by compile time switches. I don't want to put fsm_left and fsm_right into the structure file, because then I would have to set the define in that file, as well as the main file, and this can result in building the wrong device. The main file compiles code for 3 seperate products based on compile time switches. The 3 devices share a common set of structures, though not all of them are used by each build.
No, you don't. Because whatever you actually have, I'm really quite sure it doesn't look like that:
but rather more like this:
#define FSM 1 #ifdef FSM # ifdef FMSLEFT // note: currently undefined # include "fsm_left.c" # else # include "fsm_right.c" # endif #endif
Programming is all about attention to detail. So please pay attention to the formatting instructions, next time. They're right above the input window, for crying out loud!
The compiler spits up on the assignment line, with a C129 missing ';' before
"The assignment line" being this one?
Now stop and sit down for a moment. Does that really look like valid C code that the compiler should have accepted?
So I figured, something in fsm_right was incorrect.
And how did you figure that, given the error message was apparently about a line in your main source file, rather than in fsm_right.c?
I don't want to put fsm_left and fsm_right into the structure file,
Pray tell: what do you mean by "the structure file"?
because then I would have to set the define in that file, as well as the main file, and this can result in building the wrong device.
No you wouldn't have to do that. Making sure multiple C modules use the same set of compiler switches is trivially easy without having to revert back that far. That's what common header files and/or IDE/Makefile settings of compiler switches are for.
is not an assignment: c-faq.com/.../aryasgn3.html
unsigned char author[] = "whatever"; unsigned char *author = "whatever";
Hans, you are correct, I should have done the pre /pre thing. And I screwed up when typing the source line in the message
that is unsigned char author[]="whatever";
This code defines a string. Been there for 7 years.
The structure file:
I have a 'C' file that has a collection of structures in it. Lots of them. These structures define the various modes that the user can select. We are defining two new instruments. In the main code, I am selectivly compiling pointers to these structures into the code, based on a complex set of #ifdefs
I can build 6 different devices by setting different #ifdefs. I don't want to have to correlate #ifdefs between files, so in my file of structures (and constaants) I don't want to have to keep up with the #defines
in the main code #define FSM 1 #define FSMLEFT
Will build a particular device, fsmleft #define FSM 1 // #define FSMLEFT Will build a different device, (fsm right) #define POWERSENSE 1 Causes compilation such that a new power switch technique is used. this allows me to use the same source to compile code for a different hardware config. etc.
The structure file gets compiled and linked into the main file. I always link in the structure file, but don't want code specific to fsmleft and fslmright to be linked in. I could try to conditionalize the structure file such that it leaves out the support structures for fsmleft and fsmright. But then I have to remember to keep the two files #ifdefs in synch.
So I was attempting to build a selective include based on defines, and it is just not working.
You obviously ignored the message, by focusing on minutea.
The issue is that
#ifdef SOMEDEFINITION #include "some_file.c" #else #include "some_other_file.c" #endif
results in an error, in code that does not have an error, that in fact has been building just fine. When the include is commented out, there is no error. That would indicate that there was a problem in the include file. Except that I deleted the guts of the include file, so it is just an empty file, and it STILL complains about a missing semi colon.
these lines were inserted in a fully functional, compilable with no error file, and caused the compile error, which is a puzzle, because they should not have.
IDE make file switches are out of the question. I have to many to manage that way.
Complaint: How in the hell do we get rid of the idiot "watch this program" flood of posts that have hit the forum during the weekend.
Andrew: I know. I typed this in rather than pasting code. That should have been
unsigned char author[]="whatever";
I just left the [] out when I typed it in for whatever reason.
The issue however is not about that. It is about the following lines, being inserted into a totally compiler error free file,\\
#ifdef FSM #ifdef FSMLEFT #include "fmsleft.c" #else #include "fsmright.c" #endif #endif
causing an error. Assume that FSM is defined, and FSMLEFT is not defined, then #include "fsmright.c" happens.
that causes an error, regardless of whether there is anything *in* the included file. it causes the same error if the include file is error free. And the line where the error is flagged happens to be the next line of code after the last #endif.
Can you get the compiler to generate pre-processor output, and inspect that?
Yes, you can: http://www.keil.com/support/man/docs/c51/c51_preprint.htm
"inspect that"
Always a good idea for preprocessor-related issues: www.8052.com/.../29152
http://www.keil.com/forum/57051/
It is about the following lines, being inserted into a totally compiler error free file, ... that causes an error, regardless of whether there is anything *in* the included file.
The problem is that being "compiler error free", all by itself, doesn't mean much of anything. It's entirely possible that there was quite a serious mistake in that file already, which just so happened to not trigger any compiler error. Don't laugh ... it happens.
Assume that FSM is defined, and FSMLEFT is not defined, then
Frankly, the way you're trying to handle #defines, I have to doubt that. So what happenes if you do away with all that, and just put a plain
#include "fsmright.c"
in there?
And the line where the error is flagged happens to be the next line of code after the last #endif.
Then there's a good chance the actual problem was in the last line before that freshly inserted construct. Or you created the problem by inserting that construct in the middle of some statement.
I don't want to have to correlate #ifdefs between files, And I'm telling you that that's really not a good plan. There's nothing to be afraid of in #defining switches in a central file or project build configuration. Particularly for #defines used to distinguish between different build targets of the same source tree, like you're dealing with here, it's basically the only sane way of doing it. The build target selection is about as global a switch as they come. Trying to limit it to one of multiple source files won't solve any problems ... it'll only create new ones.
So I was attempting to build a selective include based on defines, and it is just not working. You're a couple steps removed yet from establishing that.
in code that does not have an error, that in fact has been building just fine. That conclusion is generally premature. Building fine is a necessary condition for having no errors, but far from being a sufficient one.
I'll have to call BS on that one. How can it possibly be too hard to manage the measly 6 switches (or even just one, if you go at it a bit less naively) that it really takes to differentiate 6 targets, just because they're in the IDE?
Not only is the IDE better at managing those compiler switches than you'll ever be editing them inside a single module (because it would keep all 6 configurations permanently), it would also entirely remove the need for what you came here for originally. Instead of #including one of several source files into another, the IDE would let you disable building all but one of them, just by ticking boxes.
Thanks. I was not aware of preprint.
The issue is still a generic one, apparently the compiler can't handle #includes of a c file inside of an ifdef.
I will try a build with preprint and see what the heck it actually produces.
You're a couple steps removed yet from establishing that.
I'd suggest you try a simple test for your self. Take the #define code I posted, and insert it in the front of a C file after the normal includes. Create an empty fsm_left.c and an empty fsm_right.c Follow it with some valid C code, and see if it doesn't throw a C129. Then put in a couple lines of code into the files and try it again.
in code that does not have an error, that in fact has been building just fine. That conclusion is generally premature.
All code except the most trivial, has errors, and even then sometimes simple code has errors. This error is however, a new build error, included by something that should be a valid C construct. This code has been building fine, and running in the field for years. There are no build errors in the build until you attempt to include a C file within a conditional define, and then bingo. This error occurs. I've seen it numerous times in the C51 compiler over the years, and it has been a headache to code around.
Building fine is a necessary condition for having no errors, but far from being a sufficient one.
Adding multiple builds with ide switches is problematic in the silabs ide. It only allows one build configuration per project.
Hans:
I never have found the problem, but decided to create another header file and include it and move the #defines to it, and include it in both c files. That way I can conditionalize both c files and only have 1 place to maintain. Thanks for the slap up the side of the head..... Grin.
... and include it and move the #defines to it, and include it in both c files.
Yes, that would be the more conventional approach!
I've never been accused of being conventional :)