Hello. I am trying to find new and exciting ways to optimize (read: shrink down) my current code and want to include an eeprom autorefresh option to cut down on variables. Basically, when I have the AutoRefreshCompile option set, I want it to create the variable "randomvariable". My code is pretty simple:
#define AutoRefreshCompile 1 #if(AutoRefreshCompile==1) { // line x extern signed short randomvariable; } // line y #endif
I am getting errors that read as follows:
VARS.H(x) error C141: syntax error near '{' VARS.H(y) error C141: syntax error near '}'
I'm guessing it is not possible to do this (if I remember correctly, variables have to be declared at the beginning and can't be in the middle of functions/code segments but maybe it's some really simple fix.
I realize this might not work but I figure it's worth a shot. Any suggestions? Thanks!
Heh, of course I know those two are different (in fact, if you look up a couple of posts, it's pretty clear I stated this already). Using brackets is actually not an issue in normal .C files either, which is why I hadn't seen this issue til now. The issue is specific to .H files and I already summarized to Erik where it appears my understanding was incorrect.
While I appreciate your help (particularly your next post, which explains the difference between statements and directives, which it appears is exactly where my understanding is lacking and I plan on doing some more reading on this after this post), sometimes I don't understand your posts. I can't decide whether the intention is to make obvious statements that we both know the answer to, to make me feel stupid, or if you didn't read some of the previous posts.
For the record, if you (or anyone else, really) had told me a few posts ago that my fundamental understanding was in directives vs statements rather than telling me to go find a C book and start reading, it could've saved us all a lot of time. Generic recommendations like "read a book" aren't anywhere near as helpful as saying "you need to read a book about the difference between directives and statements".
I'm not trying to pick on you in particular, I believe you are trying to help. But as someone who does have a decent overall understanding of C but is lacking in specifics (as you and some others were correct to point out), sometimes people just need direction where to look.
All the same, thanks everyone for your help!
You need to take care to distinguish between statements and preprocessor directives.
preprocessor directives are easily distinguished by the fact that they begin with a '#'
Braces group a number of statements into a compound statement or block - they have nothing to do with preprocessor directives.
This is standard textbook stuff - nothing specifically to do with Keil.
Yes, of course they do!
The braces are syntactically significant in the 'C' programming language.
eg,
if( condition ) a; b;
is not the same as
if( condition ) { a; b; }
is it?
So if I understand what you're saying, "if" statements need brackets if they are multiple lines long to show when a conditional statement begins and ends but, because precompiler conditionals (like "#if")have a #endif to show where they end, there is no need for brackets? I believe this is what you're saying and, if so, this makes perfect sense to me.
Is this correct or have I missed something?
without any # stuff I added brackets around void foo(void);
and got errors
it is just the brackets NOT the brackets and #
You are STILL confoosing precompiler conditions and compiler conditions. Compiler conditions can (in my opinion must) use brackets, precompiler condditionals do and can not (yes there is an exception to "can not" but I will not get into that it will just confuse the issue)
Erik
I think I had a fundamental understanding problem when I assumed:
#if(AutoRefreshCompile==1) { dofunction(variable); } #endif
was exactly the same as this:
#if(AutoRefreshCompile==1) dofunction(variable); #endif
In theory, it does the same thing (at least to my knowledge, which I'm starting to question) but apparently, the brackets themselves cause a change in the way it's read by the compiler, which causes an issue in .H files.
Any chance someone has a link or can explain to me why the brackets change things in this situation? (it looks like I had a similar misunderstanding in this thread: http://www.keil.com/forum/21544/).
John Doe Posted (why not the real name)
The file name VARS.H implies it is a header file. Header files should not contain code, so your snippet:
That doesn't actually make sense.
I think you may still need to take some more time to too fully get to grips with the meaning of braces (aka "curly brackets"), and where they are allowed...?
Hans, I ADDED preprocessor statements to REMOVE parts of code that are not always needed by setting a bit. Where did I lose you?
And as far as the previous suggestions go, you are 100% correct and brackets are not allowed in vars statements so it was a straight forward issue (and, as suggested, you are correct, I was lacking information). I now understand a bit better the limitations of what you can or cannot place in those files. I appreciate all the help! This should be the last little piece to further optimize. Thanks again for all your help!
In the primary post the error message is:
is (I assume, because I can't know) not part of a function code but part of a declaration.
If this is true then of course the { and } are not allowed, simply write:
#define AutoRefreshCompile 1 #if(AutoRefreshCompile==1) extern signed short randomvariable; #endif
or something like that...
#define AutoRefreshCompile #ifdef AutoRefreshCompile extern signed short randomvariable; #endif
If this is not true, ignore my answer.
#if(AutoRefreshCompile==1) { signed short randomvariable = 0; }
Why the braces?
"I assume the problem I'm having is Keil specific"
Why? Have you tried the same code in another compiler?
Have you looked at the preprocessor output, as suggested, to see exactly what you're creating by this?
"You assume ... I know nothing about C code"
I don't think anyone's suggested that you know nothing, but it's clear that you lack some understanding - particularly regarding the preprocessor...
Every single previous post of mine has helped me immensely when it came down to leaving coding options in the code and enabling/disabling them using #define and #if statements. Maybe you guys see my previous posts as useless or poor uses but it has been a huge help for my project.
The reason I'm placing it in my VARS.H file is I don't need those variables declared at all if certain "preprocessor" conditions are met (in my case, AutoRefreshCompile==1). I've already used the #define statement to remove segments of code, I just have never used it to remove variables. The reason I ask is because of this post here, which just required removing a single bracket:
http://www.keil.com/forum/21544/
Now, I've read the preprocessor section at the link Andrew sent me and it does demonstrate what I was already doing. However, it does not say anything about my particular issue. I assume the problem I'm having is Keil specific and it's because I'm trying to insert code before all variables are declared (which I haven't had an issue with when using Atmel. Maybe Atmel's the exception but I do know Keil handles the order of variables/functions differently).
I used the extern declaration because that demonstrated the issue I was having. I also have it in my vars.c file:
I usually don't show ALL my code because it's not necessary and would like to focus on the section I'm having an issue with. I guess I should note that I have variables declared above and below this (I guess I could move this to the end and maybe that would fix the issue). If you need more, let me know and I can give you more but I assumed this should be enough (maybe that's a bad assumption).
This is my issue (once again). You assume I haven't done the necessary homework and that I know nothing about C code and need a class. I've taken classes and maybe they haven't been as in depth as you would like but this particular case could have more to do with implementation of one particular section (in this case, preprocessors) or it could be Keil specific (though most issues I and others have are not Keil specific, so probably not). But I have done the reading, I did read the info you guys post here and, in this case, it didn't answer my question. Believe me when I say that coming to you guys is almost always a last resort, if only for the reason that some of you make asking even the most simple question a pain in the ass (and maybe that's the point).
And Hans, to answer your question, yes, I'm doing exactly that. By changing single bits, I can change how the code compiles based on the options I need. It's worked just fine in the past and I will continue to do this as it gives me additional code flexibility without adding any additional code space. If you want more information on what I'm doing, that's fine and I don't mind explaining.
optimize (read: shrink down) my current code and want to include an eeprom autorefresh option to cut down on variables
So how did you figure adding stuff whould shrink down your current code?
So, did you stop to think whether a '{' or '}' are syntactically allowed at those respecpective places? What exactly did you think those would do?
stop mixing C-preprocessor directives and normal C statements
if you can't figure out the difference, stop using it
View all questions in Keil forum