View previous topic :: View next topic |
Author |
Message |
rikotech8
Joined: 10 Dec 2011 Posts: 376 Location: Sofiq,Bulgariq
|
How to suppress warning: "Condition always FALSE" |
Posted: Sun Oct 02, 2016 3:55 am |
|
|
I use MPLAB 8.89 IDE with CCS compile 5.051.
This line Code: | #define ADC_prepareVoltageChannel() do{ set_adc_channel(0); }while(0) | causes this warning Quote: | Condition always FALSE | Could you please tell me how to make this warning to disappear (without touching the code )? Why does this warning appear in the first place? _________________ A person who never made a mistake never tried anything new.
Last edited by rikotech8 on Sun Oct 02, 2016 4:59 am; edited 1 time in total |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9243 Location: Greensville,Ontario
|
|
Posted: Sun Oct 02, 2016 4:46 am |
|
|
I'm thinking that ...
...while(0)
0 is FALSE in CCS C compiler.
so
do{...}while(0), the condition (do..while) is FALSE.
hence the 'condition is always false'...
Jay |
|
|
rikotech8
Joined: 10 Dec 2011 Posts: 376 Location: Sofiq,Bulgariq
|
|
Posted: Sun Oct 02, 2016 5:03 am |
|
|
Yes, but this is typical C construct. I dont want to see this warning any more. Is there options or flags to disable specifically this warning? I am going to have plenty of these in my code, which means dirty console after build. Quite annoying. _________________ A person who never made a mistake never tried anything new. |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9243 Location: Greensville,Ontario
|
|
Posted: Sun Oct 02, 2016 5:32 am |
|
|
OK.. in the CCS C manual there is a way to 'turn off' Warnings. I'm not on the eng PC but you can disable them ,either specific ones and maybe 'globally'.
if you can't find it fast...ask Google !
I know the one about 're-entrancy' can be turned off.....
Jay |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19538
|
|
Posted: Sun Oct 02, 2016 6:38 am |
|
|
Why on earth would you want this construct anyway?.
It does nothing, and will in fact be removed by the compiler.
Since 0 is always FALSE, the loop will never occur.
If you look at the assembler generated, no loop instruction or test will be generated at all, which is why there is a warning....
It will warn you if a line involving a number is doing nothing. If you use 'TRUE' or 'FALSE' instead it will not warn you (but no code will still be generated).
It'll just generate the single instruction line for set_adc_channel(0); nothing else. |
|
|
rikotech8
Joined: 10 Dec 2011 Posts: 376 Location: Sofiq,Bulgariq
|
|
Posted: Sun Oct 02, 2016 9:58 am |
|
|
@Ttelmah Quote: |
Why on earth would you want this construct anyway?. |
Ok here is a better example:
Code: | #define ADC_setUpAdc() do{ setup_adc(ADC_CLOCK_INTERNAL);\
setup_adc_ports(AN0_TO_AN2); }while(0) |
Quote: | . If you use 'TRUE' or 'FALSE' instead it will not warn you | Why?
What are these two evaluated to?
Is there a way to see the code after the preprocessor? _________________ A person who never made a mistake never tried anything new. |
|
|
septillion
Joined: 21 Jan 2010 Posts: 13
|
|
Posted: Sun Oct 02, 2016 3:01 pm |
|
|
Ttelmah wrote: | .
Since 0 is always FALSE, the loop will never occur. |
No it does not. The loop will occur exactly once. ;)
But that still leaves me with why? It's just
Code: |
#define ADC_setUpAdc() setup_adc(ADC_CLOCK_INTERNAL);\
setup_adc_ports(AN0_TO_AN2);
|
|
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Sun Oct 02, 2016 4:40 pm |
|
|
rikotech8 wrote: |
If you use 'TRUE' or 'FALSE' instead it will not warn you.
Why?
|
I think the compiler is deliberately written that way.
rikotech8 wrote: | What are these two evaluated to? |
Make a test program. Run it in MPLAB vs. 8.92 simulator. I get the following output:
Test program:
Code: | #include <18F46K22.h>
#fuses INTRC_IO,NOWDT,PUT,BROWNOUT,NOLVP
#use delay(clock=4M)
#use rs232(baud=9600, UART1, ERRORS)
//======================================
void main(void)
{
printf("%x \r", TRUE);
printf("%x \r", FALSE);
while(TRUE);
} |
|
|
|
rikotech8
Joined: 10 Dec 2011 Posts: 376 Location: Sofiq,Bulgariq
|
|
Posted: Mon Oct 03, 2016 12:34 am |
|
|
Quote: | But that still leaves me with why? It's just.... |
Consider this example:
Code: | #define ADC_setUpAdc() setup_adc(ADC_CLOCK_INTERNAL);\
setup_adc_ports(AN0_TO_AN2);
if(someCondition)
ADC_setUpAdc();
|
setup_adc_ports(AN0_TO_AN2) will always be executed, no matter what the the if condition evaluates to. But if we enclose them into a do/while loop,
Code: | #define ADC_setUpAdc() do{setup_adc(ADC_CLOCK_INTERNAL);\
setup_adc_ports(AN0_TO_AN2);}while(0)
if(someCondition)
ADC_setUpAdc(); |
both expressions will be executed only if the expression into the if statement (someCondition) is true. Here is the code after the preprocessor:
First example(without do/while):
Code: |
if(someCondition)
setup_adc(ADC_CLOCK_INTERNAL);
setup_adc_ports(AN0_TO_AN2); // outside the IF flow control
|
Second example with do/while
Code: |
if(someCondition)
do{setup_adc(ADC_CLOCK_INTERNAL);
setup_adc_ports(AN0_TO_AN2);}while(0); // as if it is compound statement under the IF's flow control
|
This way we get function like macro, that does not return value.
Quote: | I think the compiler is deliberately written that way. |
Why? To make the code less portable? _________________ A person who never made a mistake never tried anything new.
Last edited by rikotech8 on Mon Oct 03, 2016 1:26 am; edited 3 times in total |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Mon Oct 03, 2016 12:50 am |
|
|
Quote: | But if we enclose them into a do/while loop,
#define ADC_setUpAdc() do{setup_adc(ADC_CLOCK_INTERNAL);\
setup_adc_ports(AN0_TO_AN2);}while(0);
both expressions will be executed only if condition is true. |
That's not true. A do-while() loop always executes the body at least once.
See the note in the Syntax section in this official Microsoft MSDN page:
Quote: |
The expression in a do-while statement is evaluated after the body of the
loop is executed. Therefore, the body of the loop is always executed at
least once. |
If you want a loop that will conditionally execute based on the expression,
then use a pure while() loop. Example:
Code: |
while(expression)
{
// body of loop.
} |
If the expression is true, it will execute at least once. If the expression
is false, it will never execute. Read the MSDN article on while():
https://msdn.microsoft.com/en-us/library/y1tscb5y.aspx
Quote: | I think the compiler is deliberately written that way.
Why? To make the code less portable? |
I don't get your problem. We're talking about CCS not giving an
annoying warning about a while(TRUE) loop. If I write a while() loop
with while(TRUE) in it, I know the condition is always true. I don't need
the compiler telling me what I already know, just by inspection. |
|
|
rikotech8
Joined: 10 Dec 2011 Posts: 376 Location: Sofiq,Bulgariq
|
|
Posted: Mon Oct 03, 2016 1:28 am |
|
|
@PCM programmer
I think you misunderstood my point. I edited my previous post in order to make it clearer. _________________ A person who never made a mistake never tried anything new. |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Mon Oct 03, 2016 1:43 am |
|
|
I don't understand your problem, and I don't want to participate in this thread anymore. |
|
|
rikotech8
Joined: 10 Dec 2011 Posts: 376 Location: Sofiq,Bulgariq
|
|
Posted: Mon Oct 03, 2016 1:58 am |
|
|
I was trying to explain why I need this construct, because I was asked to. My problem is the warning I get from the compiler after this construct. _________________ A person who never made a mistake never tried anything new. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19538
|
|
Posted: Mon Oct 03, 2016 2:40 am |
|
|
septillion wrote: | Ttelmah wrote: | .
Since 0 is always FALSE, the loop will never occur. |
No it does not. The loop will occur exactly once. ;)
But that still leaves me with why? It's just
Code: |
#define ADC_setUpAdc() setup_adc(ADC_CLOCK_INTERNAL);\
setup_adc_ports(AN0_TO_AN2);
|
|
No. The _pass_ through the code will occur once. There will be no 'loop'.
As I said it'll just code as the single set_adc_channel instruction.
The compiler looks a the code and says 'the actual loop is doing nothing at all, it is just single pass code I will warn the writer that what they are doing is pointless and remove the loop'.
The definition of 'what is a loop', comes as:
"In computer programming, a loop is a sequence of instruction s that is continually repeated until a certain condition is reached. Typically, a certain process is done, such as getting an item of data and changing it, and then some condition is checked such as whether a counter has reached a prescribed number.".
This does not code as a 'loop'. It is single pass, and the compiler knows this and point it out.
Many versions ago, CCS would warn if any condition behaved like this. However it led to complaints where things like the 'forever' loop would warn, so they changed it and removed the warning if the test was on a 'TRUE' or 'FALSE' define. |
|
|
RF_Developer
Joined: 07 Feb 2011 Posts: 839
|
|
Posted: Mon Oct 03, 2016 3:47 am |
|
|
Hmm, I might be late to the party, but I just wanted to say that this is a case where one misunderstanding has lead to the use of a very unconventional code structure. The replies so far have concentrated on that unconventional code rather than looking at the underlying problem: a poorly constructed macro expansion.
Yes, a loop that only executes once is not a loop, and, I feel, the compiler is reasonable to warn about something that leads to that. I say that because the loop is not working as most people might expect: i.e. not as a loop at all. However, I view the do...while(0) as a red herring. It is not the main problem.
The root cause is that in an if statement the macro doesn't expand as you expect. An if conditionally executes takes one statement. In this case without the strange loop, it will only execute the setup_adc(), if indeed it can be executed as it is not an actual C function call, rather it is a request to the compiler to replace it by functionally equivalent machine code. The second statement, the setup_adc_ports "call" (again it is not a real function call) will ALWAYS be executed because the semicolon at the end of the setup_adc() will end the if statement.
If you want both statements to be executed together they have to be a block, making them a compound statement. That is effectively what you have done by the do..while, but clumsily. Indeed you don't need the do...while at all, just the braces. you can do this in the macro:
Code: |
#define ADC_setUpAdc() { setup_adc(ADC_CLOCK_INTERNAL);\
setup_adc_ports(AN0_TO_AN2); }
|
Another way to do this, one I personally prefer, is to make this into an actual function, rather than a function-like macro, and inline it to avoid the speed and stack overhead of the function call mechanism. This gives multiple copies of the code, but the macro way would do too:
Code: |
#inline
void ADC_setUpAdc()
{
setup_adc(ADC_CLOCK_INTERNAL);
setup_adc_ports(AN0_TO_AN2);
}
|
In both cases there is no need for the do...while(0). |
|
|
|