CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

How to suppress warning: "Condition always FALSE"
Goto page 1, 2  Next
 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
rikotech8



Joined: 10 Dec 2011
Posts: 376
Location: Sofiq,Bulgariq

View user's profile Send private message

How to suppress warning: "Condition always FALSE"
PostPosted: Sun Oct 02, 2016 3:55 am     Reply with quote

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 Smile )? Why does this warning appear in the first place? Confused
_________________
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

View user's profile Send private message

PostPosted: Sun Oct 02, 2016 4:46 am     Reply with quote

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

View user's profile Send private message

PostPosted: Sun Oct 02, 2016 5:03 am     Reply with quote

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

View user's profile Send private message

PostPosted: Sun Oct 02, 2016 5:32 am     Reply with quote

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

View user's profile Send private message

PostPosted: Sun Oct 02, 2016 6:38 am     Reply with quote

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

View user's profile Send private message

PostPosted: Sun Oct 02, 2016 9:58 am     Reply with quote

@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

View user's profile Send private message

PostPosted: Sun Oct 02, 2016 3:01 pm     Reply with quote

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

View user's profile Send private message

PostPosted: Sun Oct 02, 2016 4:40 pm     Reply with quote

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:
Quote:

01
00

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

View user's profile Send private message

PostPosted: Mon Oct 03, 2016 12:34 am     Reply with quote

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

View user's profile Send private message

PostPosted: Mon Oct 03, 2016 12:50 am     Reply with quote

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

View user's profile Send private message

PostPosted: Mon Oct 03, 2016 1:28 am     Reply with quote

@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

View user's profile Send private message

PostPosted: Mon Oct 03, 2016 1:43 am     Reply with quote

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

View user's profile Send private message

PostPosted: Mon Oct 03, 2016 1:58 am     Reply with quote

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

View user's profile Send private message

PostPosted: Mon Oct 03, 2016 2:40 am     Reply with quote

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

View user's profile Send private message

PostPosted: Mon Oct 03, 2016 3:47 am     Reply with quote

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).
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Goto page 1, 2  Next
Page 1 of 2

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group