|
|
View previous topic :: View next topic |
Author |
Message |
bcfd36
Joined: 14 Apr 2015 Posts: 28 Location: Boulder Creek, CA
|
Expected warnings not generated |
Posted: Wed Aug 26, 2015 8:06 pm |
|
|
PIC18F66J50
Compiler Version 5.018
I am expecting a boatload of warnings with the following program. The manual and the Help seem to indicate I should get warnings when I do some of the stuff that follows. Is there something I am not turning on, or something I missed somewhere?
I'm assigning numbers to enum vars. I am using uninitialized variables in calculations. I have a function that is not called. Etc.
Code: | #include <18F66J50.h>
#case
#ignore_warnings NONE
int8 a = 5 ;
char ch = '5';
int16 b = 5 ;
long long int c = 40000 ;
int16 d = 0x0005 ;
typedef enum
{
fred=1, wilma, barney, betty
} flintstonesType ;
flintstonesType e = fred ;
flintstonesType f ; // not initialized
int g ; // not initialized
int I_am_not_called() // expecting a warning for not being called
{
int a = 40 ;
#warning this is embedded warning text
}
void main()
{
typedef enum {red, yellow, blue} colorType;
colorType color ;
color = red ;
color = 10 ; // expecting warning 209
c = d + a + b + f + g ; // expecting a warning: Variable used before assignment is made.
ch++ ;
e = e++ ;
e = 10 ; // expecting warning 209
while(1)
{
ch++ ;
}
} |
I get the following warnings:
Code: | >>> Warning 224 "temp.c" Line 25(12,42): #warning this is embedded warning text
>>> Warning 208 "temp.c" Line 22(5,20): Function not void and does not return a value I_am_not_called
>>> Warning 203 "temp.c" Line 44(1,1): Condition always TRUE
>>> Warning 202 "temp.c" Line 24(8,9): Variable never used: a
Memory usage: ROM=0% RAM=1% - 1%
0 Errors, 4 Warnings.
Build Successful. |
Has this been asked before? I looked for about 1/2 hour but didn't find anything directly applicable. _________________ D. Scruggs |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19552
|
|
Posted: Thu Aug 27, 2015 12:48 am |
|
|
'C' has no requirement at all for a value to be assigned before a variable is used. This is a feature of other languages.....
Java, Python, particularly any object orientated language.
C# for example adds this as an optional error, but it is not an error in C.
Hence no warning for this.
Look at:
<https://en.wikipedia.org/wiki/Uninitialized_variable>
Particularly note the last line.
#zero_ram will initialise all variables to zero.
C is also not a typed language. It is perfectly legal to assign any type of variable to any other. The language will attempt to convert the value from one type to the other when assignment is made, but no type checking is performed. It is actually a powerful 'feature' of the language, but brings with it the requirement that you perform this checking. In fact an enum, in C, is an int, so e=10, is perfectly legal.
It is also perfectly legal to declare a function that is not called. If it wasn't you would have thousands of warnings when you include things like the maths libraries, since these declare all the maths functions. Code is not physically generated for a function, until it is called. If you look at the list file, a function is ignored completely until it is actually called.
You would get "function used, but not defined", if you declared a function prototype, but no actual code, but again, only when you actually try to call it.
So these warnings are _not_ expected. With C. |
|
|
bcfd36
Joined: 14 Apr 2015 Posts: 28 Location: Boulder Creek, CA
|
|
Posted: Thu Aug 27, 2015 3:25 am |
|
|
A couple of things. I know C very well, having written in it for over 35 years, off and on. I know that everything I did was perfectly legal.
I was asking why there were no compiler warnings when the manual pretty clearly indicated that they would be generated. Specifically, warning #209 when you assign a value to a enumerated type. The manual also talked about other warnings that would be generated, so I put code in that should have generated these warnings.
It is interesting that "while(1)" generates a warning but "while(TRUE)" does not.
The following is extracted from the manual, page 325, the section titled Compiler Warning Messages
Quote: | #error/warning
Assignment inside relational expression
Although legal it is a common error to do something like if(a=b) when it was intended to do if(a==b).
Assignment to enum is not of the correct type.
This warning indicates there may be such a typo in this line:
Assignment to enum is not of the correct type
If a variable is declared as a ENUM it is best to assign to the variables only elements of the enum. For example:
Code: | enum colors {RED,GREEN,BLUE} color;
...
color = GREEN; // OK
color = 1; // Warning 209
color = (colors)1; //OK |
|
That looks pretty clear to me. So the manual is wrong? _________________ D. Scruggs |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19552
|
|
Posted: Thu Aug 27, 2015 4:02 am |
|
|
Undoubtedly. There are a lot of errors in the manual.
I'd suspect the enum one was one they had to get rid of, for ANSI C.
Read this:
<https://msdn.microsoft.com/en-us/library/whbyts4t.aspx>
Note particularly this paragraph:
"In ANSI C, the expressions that define the value of an enumerator constant always have int type; thus, the storage associated with an enumeration variable is the storage required for a single int value. An enumeration constant or a value of enumerated type can be used anywhere the C language permits an integer expression."
Note the MS example specifically assigning a numeric value to the enum.
Then the idea of giving a warning on unused functions, just does not work in C, since this is the way function libraries are handled, and in fact it is specifically legal. They may well have tried to add a warning, then realised they were shooting themselves in the foot. |
|
|
RF_Developer
Joined: 07 Feb 2011 Posts: 839
|
|
Posted: Thu Aug 27, 2015 4:07 am |
|
|
bcfd36 wrote: | So the manual is wrong? |
Of course the manual's wrong! ... Well, there are certainly many errors, instances of confusions and missing information. There always will be - there's nothing particularly clever about finding them. The question is this one of them? My guess would be yes, I suspect it might be a warning that is generated only in ANSI compatibility mode, where I'd expect type checking to be a little stricter that in the "legacy C" mode. As such it probably rates as confusing due to missing information.
One problem that often catches people out is the manual comes in two version, one for 24 et all PICs (PCD version) and one for the 16/18s etc. (PCM/H version). It is not at all easy to tell which version you are looking at, and switching between the two is arguably not that straightforward.
In any case, if anyone finds a problem with the manual, and there are many, then tell CCS. By all means tell us for information, but as we are users we can't do anything about it other than to check and say "yes, we see that too." |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19552
|
|
Posted: Thu Aug 27, 2015 4:12 am |
|
|
On the enum, it is actually the other way round!....
Enum's are specifically typed as integers in ANSI C, and are actually required to be interchangeable with integers!....
Thing is that if you had an error and went looking in the manual, it'd tell you what the errors were. However I think the list of errors in the manual covers lots that they may have thought about doing and never got round to handling. So trying to use the manual 'backwards' is never going to work. |
|
|
bcfd36
Joined: 14 Apr 2015 Posts: 28 Location: Boulder Creek, CA
|
|
Posted: Thu Aug 27, 2015 1:27 pm |
|
|
I sent a query to the CCS people to see what they had to say about their warning messages. We'll see what they have to say, if anything.
Ttelmah, you seemed to miss my point. Maybe I wasn't clear. I was not asking what C could or could not do, I am well aware of that. I was asking specifically about compiler warnings. We can debate all day (and I choose not to) about whether or not you should add integers to enums or not and about their use in general. I would say if you are doing things to enums that could take them out of range, you are not properly using the enum type and should be using some other data type.
It looked to me like the warnings they implied the compiler would generate were mostly saying "Are you really sure you want to do what you are doing on line xxx?", which in not a bad thing at all. Maybe you inherited a mass of code and there are functions/procedures/subroutines that are no longer called, but still there for some reason. Like I did. The manual says these will be flagged with a warning. It would be nice to get rid of the dead code. If the code is not truly dead, the warning is not a problem. But the warning could tell you about something you didn't know or was not clear.
I'm done until, if ever, I hear back from CCS. I'm off to the wine country. Hopefully, it is not on fire. I don't mind a little smokey taste in my Cabernet, but I don't want it in the air in which we are drinking it.
To all of you, thanks for your time. _________________ D. Scruggs |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19552
|
|
Posted: Thu Aug 27, 2015 2:15 pm |
|
|
The manual does not say that 'these will be generated'. What it says is 'this is the meaning of this message'. As RF developer points out, some of the messages depend on the mode the compiler is being run in (CCS2/CCS3/CCS4/ANSI/PCB/PCM/PCH/PCD). Also some won't exist at all....
It is a pity, but CCS has never published a proper list of error number, and/or which modes they actually apply in.
I actually think the 'list' was created by cut and paste from another compiler (possibly something like C+), probably by a 'hopeful' marketing person, and has not been reduced to meet C limitations.....
There are a lot of problems with the mixed versions, so functions that say they use a particular type, when on PCD for example the type changes. |
|
|
RF_Developer
Joined: 07 Feb 2011 Posts: 839
|
|
Posted: Fri Aug 28, 2015 2:14 am |
|
|
Quote: | I would say if you are doing things to enums that could take them out of range, you are not properly using the enum type and should be using some other data type. |
Such things are language design issues which have been hotly debated over decades. C is weakly typed, as I'm sure you are aware. It didn't even have an enum type at first. When it was implemented it wasn't done as a truly separate type, but rather a sub-type of int. It was, and still is, as a set of labels for integer values; effectively as sets of labels for integers. You can, quite legally, assign values of one enum to another, or any value to any enum; the compiler should not, by design, complain. C doesn't, and was not intended to protect the programmer. That is one of its greatest strengths, and in the hands of many programmers, arguably also one of its greatest weaknesses. In short if you want, or even accidentally assign 125 to a enum of three values, that's your problem; the compiler is not meant to spot that or warn about it.
Also, C has no range checking, either at compile time or compile time. If you want to assign an out of range value to anything, C will oblige as best it can, with at times unpredictable, or at least unexpected especially for the inexperienced, results. It will happily allow us to set an unsigned integer to -567 for example. It will also allow you to attempt to access the 17th, or even the -2nd member of an array of 2 elements. This allows faster compiling and significantly faster run times and smaller code volumes. Because C has no range checks it is faster and leaner, and that too has been a major factor in its success and continued use as THE first choice for embedded programming, long after many other languages of its era have fallen by the wayside.
Other languages, including C-derived ones such as C++ and C#, have stronger typing, and "know" the difference between enums and integers and won't allow assignment of one to the other without explicit casting or other type conversions where appropriate. Also many have compile and runtime range checking, with all the baggage that brings with it. Great when you've got processor power to spare and RAM by the megabyte.... Just don't bring expectations from such languages to the C party. |
|
|
newguy
Joined: 24 Jun 2004 Posts: 1909
|
|
Posted: Fri Aug 28, 2015 7:01 am |
|
|
RF_Developer wrote: |
Also, C has no range checking, either at compile time or compile time. |
I'd argue that in some cases there is a range check but it's not really a range check per se. For example:
Code: | unsigned int8 j;
for (j = 0; j < 256; j++) {
// do something here
} |
The compiler will warn that the condition in the for () is always true. Not really a range check but the end result is that you are alerted to a range issue. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19552
|
|
Posted: Fri Aug 28, 2015 7:38 am |
|
|
That is the difference between 'C' having no range checking, and the compiler.
The compiler will in some specific cases give some warnings. For instance if you try to print a 16bit int, with %u, and as you say for your example it knows that in this case the code results in a condition that can never go FALSE.
However in neither case is it actually 'range checking', but results 'by implication' of the range. So as you say, not a 'range check per se'. |
|
|
bcfd36
Joined: 14 Apr 2015 Posts: 28 Location: Boulder Creek, CA
|
Expected warnings not generated - Answer from CCS |
Posted: Mon Aug 31, 2015 11:38 am |
|
|
I received the following from CCS last Friday, after I had submitted a notification of the issue we have been discussing:
Quote: | You are right the 209 seems broke. It will be fixed in the next release. |
So it seems like it used to exist (as implied by the manual), it broke at some point, and they are going to put it back. I feel vindicated, triumphant, exaltant. I need to get a life.
I think this is a good thing. I like it when the compiler is smart enough to let you know you MIGHT be making a mistake you didn't realize you may be making. I would say that if you are adding 125 to your 3 value enum, 90% of the time it is a mistake or what you are writing is very kludgey code. But, being C (and not C++ or ADA or one of the other strongly typed languages) you are allowed to shoot your foot off.
Of course, being C, there may be a really good reason for adding 125 to your 3 value enum. And most C writers will just have something like
Code: | voltage = (float)(PURPLE + 125) ; |
and not a comment in sight. Or more probably
Code: | v=(float)(P+125L) ; |
I love RF engineers. _________________ D. Scruggs |
|
|
|
|
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
|