I understand the rule about always specifying signed or unsigned, but in this case if the compiler (as the default in Microchip’s XC16) is for the default type of char to be unsigned this gives warnings when passing strings.
If you want to remove the warning, cast the string to a const char * const when you pass it in. I think this is done in lots of places in the demo code.
FreeRTOS works with something like 18 different compilers, and we aim to have 0 warnings when building the FreeRTOS code. That is not easy, and requires that the user sometimes also has to cast values.
In this case, if the const casts were removed from the FreeRTOS code then you risk wasting RAM space at low optimisation. If the type was removed from the cast then you would fail MISRA rule checks. If you changed the type in the cast you would just create warnings with compilers that until that time didn’t generate warnings, while fixing warnings in compilers that previously did generated warnings (without explicit casts).
It is a pity that MISRA (and perhaps indeed C) does not recognize the difference between a char character and a char small integer, but since you have gone to such trouble it would seem appropriate (even if they are only debug tags) to define (or typedef) a string type that is set in the portable layer to a signed or unsigned char as appropriate.
My two cents (and with the demise of our penny it gets rounded to what it is really worth!)
Yes, I will also be happy if there were more typedefs used in kernel code that is defined in portable layer (at least in API). I know that yours target is compatibility with MISRATA standard but writing redundand attributes like “signed portBASE” where on most 32 and 16 bit platfroms portBASE is signed by default or mentioned above casting “const char *” to is a little pain in the ass.
What purpose is this casting? Would not be better to typedef in portable layer portCHAR (on my port it is already defined) to char or unsigned char and use this type when string parameter is needed? Maybe to far example but what about the case when I need to use wide chars?
Another example: you are using type portSTACK_TYPE to specify stack type parameter type, but size is not typed (maybe portSIZE_TYPE should be introduced). There are many more places like those above.
From my point of view this is inconsistent and forces large amount of redundant code to be written by programmer.
Sorry for so much of complaints but I had to said this
This is a very subjective thing. Every change we make to please you will upset somebody else, or in this case probably more than one somebody else. I’m sorry we can’t please all of the people all of the time. I have in fact just added in more of these in the latest SVN checkin directly as a result of user feedback that some were missing.
but writing redundand attributes like “signed portBASE”
In that case the ‘signed’ is absolutely not redundant. You have to look at the history of the code. Originally in many ports portBASE_TYPE was a char, and in line with I think every coding standard I have seen, and in MISRA, plain unqualified char types can simply not be used. Probably three quarters of the compilers supported have plain chars unsigned by default (because they are embedded compilers), and the other quarter have then
where on most 32 and 16 bit platfroms portBASE is signed by default
Would not be better to typedef in portable layer portCHAR (on my port it is already
defined) to char or unsigned char and use this type when string parameter is needed?
Historically this was done, guess what, people complained and it was removed. Now you want them back again, so again my point is being made quite clearly.
Another example: you are using type portSTACK_TYPE to specify stack type parameter type,
but size is not typed (maybe portSIZE_TYPE should be introduced).
The only real place in the code where the size of a type is important is for pointers, and there is a pointer size type for those ports that require it (the ones with eccentric number of bits for the address bus or different memory models).
As it happens - I actually agree with you on a lot of points. If you look at the newer FreeRTOS components that are provided directly by us you will see all types come from stdint.h - and typedefs end with a ‘_t’, like C’s standard size_t. I would like to change the convention used in FreeRTOS itself to match that, but to do so would result in a lot of complaints about backward compatibility being broken (the prototype of all the API functions would change). Still, version 8 will be released as soon as we find time to document it, and as that is a major version number update that would be the time to do it.
You used the work most yourself there, which sort of is my point.
Would it be worth pointing out that for 9 years now the MIRSA specification now requires that “plain” char be used for “characters” and signed char and unsigned char only be used for small numeric values so FreeRTOS is currently NOT MIRSA complient to the latest spec (MIRSA-C:2004). (Rules MIRSA-C:2004 6.1 and 6.2, REQUIRED)
I know this would be a major change in compatibility but perhaps FreeRTOS could define a type for characters, and default this to signed char unless something is set in FreeRTOSConfig.H, which would allow the “proper” definition to be used.
I’m not sure which MISRA version I have, probably the original, but I use Lint as the checker. That is good information, and I probably missed it as the use of standard types is one of the fey documented exceptions.
I wonder if we could change the code to use stdint.h types (as per FreeRTOS+CLI, FreeRTOS+UDP, etc.) and then provide a compatibility header file for people to include who want to update to the V8 code, but not have to change their own code. That might be possible.
Before I posted I had to look up the MISRA rules - and got the old ones!. The new ones seem better on several fronts (otherwise known as more to my liking :)), though they went backwards with macros now requiring that #undef not be used.
Does anyone know what their objection is - I have used macros/undef to create create tables from a single “source file”, the classic being enums and their string equivalents which seems an excellent use of macros - though not to MISRA’s liking.
Using stdint types would be fine with me, and define the old types for compatibility. If you want to strictly follow MIRSA you need a
typedef char FreeRTOS_char;
Statement I believe, as I think the “silly” rule of never using built in types applies even though another rule says the type must be char. I suppose that does allow you at some future point to change it to wchar_t, but then all string constants will need to be changed too.
My guess to the objection of #undef is that you can abuse it and get unsafe code by #undef-ing a “Global” macro to a different value. This is sort of a different case, where the macro is really a “parameter” to the include file, and in my opinion actually makes the source code “safer”, being able to parse the header multiple times to make sure related data structures match.
It does have the danger of confusing some people though, I had always thought of it as a standard technique, but some programmers I have worked with had never seen it and needed help to understand the code. One they understood it though, they appreciated the convinience and safety of keeping the structures in sync.