EmbeddedRelated.com
Forums

MISRA Rule 45

Started by Mikael Lundqvist March 14, 2005
In article <4235B55D.44F1CDAB@yahoo.com>, CBFalconer wrote:
>> *(int * const)(0x67a9) = 0xaa55; > > You can't cast the lvalue. You can only cast the value to be put > into it. Illegal everywhere.
I don't have a compiler or tool that complains about the above, other than noting that the "const" is meaningless. What in the standard indicates this is illegal? -- John W. Temples, III
CBFalconer <cbfalconer@yahoo.com> wrote:

>> *(int * const)(0x67a9) = 0xaa55; > >You can't cast the lvalue. You can only cast the value to be put >into it. Illegal everywhere.
It isn't casting an lvalue it is casting a constant to a pointer which is dereferenced to yield an lvalue.
nospam wrote:
> CBFalconer <cbfalconer@yahoo.com> wrote: > >>> *(int * const)(0x67a9) = 0xaa55; >> >> You can't cast the lvalue. You can only cast the value to be put >> into it. Illegal everywhere. > > It isn't casting an lvalue it is casting a constant to a pointer > which is dereferenced to yield an lvalue.
Touche. A point, a veritable point. -- "If you want to post a followup via groups.google.com, don't use the broken "Reply" link at the bottom of the article. Click on "show options" at the top of the article, then click on the "Reply" at the bottom of the article headers." - Keith Thompson
Hans-Bernhard Broeker wrote:

> The main problem is that you even tried to apply a portability / > safety oriented C coding ruleset such as MISRA to this strictly > hardware-specific task. That makes no sense.
Since, somewhere in the code, there HAS to be a translation point between the 'standard' language and something that accesses the underlying hardware, how does the MISRA standard suggest this be done? No use saying "do it in assembler"- a safety and portability standard couldn't even contemplate such. A HAL shunts the problem a stage down the line, but it's still necessary somewhere. Paul Burke
Tim,
thanks for your comment
> You could also define all the relevant symbols in an assembly file, then > define the symbols as "extern" in your code. > > If MISRA has some way of temporarily turn off a rule (i.e. with a > "#pragma" command or the like) then it may be a good thing to do, with a > slew of comments as to why you're doing it.
Again, as you mention it, MISRA is circumvented. This is one way to do it. But Assembly is not really necessary. The same can be done in C. Another detour is the creation of object files or a library containing 'Non MISRA checked' functions with proper protoyping. There are tools on the market that allow to disable MISRA rules or use special configuration files. One thing common to all: Proper documentation is mandatory. with kind regards /jan
Hi all,
As a followup to CBFalconer's contribution and the resulting discussion:
It is always possible to find a hair in the soup. ;-)

To clarify some issues:
The example was taken from an article in the embedded systems programming
magazine (Programmer's test) which I find very enlightening because it
reflects 99% of the C language related support questions I get to handle
every day.

The 'registers' I was mentioning were meant to be so called Special Function
Registers of peripherals on an MCU.

It is common procedure (as with many toolchains I know) to implement header
files for MCU derivatives this way.
This goes for GNU as well as vendor specific tools alike.

Before posting I have tested the example with a little testcase.

The example:

unsigned int *ptr;
ptr = (unsigned int *)0x67a9;

*ptr = 0xaa55;

*(int * const)(0x67a9) = 0xaa55;



should better have been posted like:

/******* memio.c ********/
volatile unsigned int* SFR_IO_addr = (volatile unsigned int* )0x1500;

unsigned int *ptr;

void foo(void)
{
 ptr = (unsigned int *)0x67a9; /* assign address */
 * ptr = 0xaa55; /* store datum into address */
 *(int * const)(0x67a9) = 0xaa55; /*The expression is legal but somewhat
cyptic.*/

 while(*SFR_IO_addr==0)
 {
   ; /* wait forever while SFR_IO_addr = 0 */
 }
}

void main(void)
{
 foo();
}

/******* EOF memio.c ********/
So we do not run into the 'uninitialized pointer' issue CBFalconer
mentioned.

I hope this clears the fog a bit.

with kind regards
/jan


CBFalconer wrote:
> nospam wrote: > >>CBFalconer <cbfalconer@yahoo.com> wrote: >> >> >>>>*(int * const)(0x67a9) = 0xaa55; >>> >>>You can't cast the lvalue. You can only cast the value to be put >>>into it. Illegal everywhere. >> >>It isn't casting an lvalue it is casting a constant to a pointer >>which is dereferenced to yield an lvalue. > > > Touche. A point, a veritable point. >
This case would be more clear with other way of setting the parentheses: *((int *)0x67a9) = 0xaa55; (The example is bad, many architectures are not happy with a longer datum (int, 16 or 32 bits) loaded to an odd address). -- Tauno Voipio tauno voipio (at) iki fi
On Tue, 15 Mar 2005 08:25:56 +0000, Paul Burke <paul@scazon.com>
wrote:

>Hans-Bernhard Broeker wrote: > >> The main problem is that you even tried to apply a portability / >> safety oriented C coding ruleset such as MISRA to this strictly >> hardware-specific task. That makes no sense. > >Since, somewhere in the code, there HAS to be a translation point >between the 'standard' language and something that accesses the >underlying hardware, how does the MISRA standard suggest this be done? >
The _best_ thing to be said of MISRA is that it recognizes it is unreasonable to expect complete compliance, that the rules will have to be broken from time to time (indeed, rule 3 says "break rule 1" in almost so many words), and gives a procedure for doing so. In MISRA 1, it is described in section 5.2.3 "Deviation procedure." I don't have a copy of MISRA 2 yet... Regards, -=Dave -- Change is inevitable, progress is not.