Re: Bug found in GCC-AVR/ AVRStudio

From: David (david.nospam_at_westcontrol.removethis.com)
Date: 01/19/05


Date: Wed, 19 Jan 2005 10:48:32 +0100

On Tue, 18 Jan 2005 20:31:42 -0600, Jack Klein wrote:

> On Tue, 18 Jan 2005 11:12:06 +0100, David
> <david.nospam@westcontrol.removethis.com> wrote in comp.arch.embedded:
>
>>
>> is undefined. I was under the impression that this was legal, albeit bad
>> programming practice. Perhaps it is legal under more general or older C
>> standards (there are so many), but illegal in ANSI C ?
>
> Not unless there was a standard for C other than the original de facto
> one, K&R 1 published in 1978. Even that text stated that the result
> of attempting to modify a string literal was undefined.
>

OK - thanks for correcting me.

>> In the specific case of the AVR, a compiler that puts const data in flash
>> is still breaking the standards, since code such as:
>>
>> int i = 100;
>> const int *p = &i;
>>
>> *is* legal. You can add a const qualifier if you want. On the avr,
>> assembly code for reading flash and reading ram are quite different, so
>> this code would not work on compilers (such as ImageCraft's) which put
>> const data in flash.
>
> Yes, this code is perfectly legal, and it causes no problem with
> implementations that put code into EPROM/flash/write-protected memory.
> You can always assign a pointer to a more qualified (with const and/or
> volatile) object with the address of a less qualified object of the
> same type. And if the compiler put 'i' in read-only memory it would
> be seriously non-conforming. Because:
>
> *((int *) p) = 100;
>
> ...is legal code and does what you expect. You can cast away
> "const-ness" as long as the object was not actually defined const.
>
> Adding the const qualifier to the type pointed to by a pointer does
> not mean it can actually only point to const objects. It merely says
> that you will not modify the object through the pointer.
>
> If you cast away the const and attempt to modify the object, it is
> well defined if the object is not const, undefined if it is.
>

Yes, that's my understanding too. But on an architecture like the AVR,
accessing data in flash and data in ram is done in different ways.
Consider the following setup:

void outputConst(const int *p) { printf("%i", *p); }
const int c = 10;
int v = 20;
void testC(void) { outputConst(&c); }
void testV(void) { outputConst(&v); }

Assume these are in different files, or there is no global optomisation or
other tricks. Both testC and testV are valid code, and should work fine.
But if c is placed in flash and v in ram, then there is no way to
implement outputConst in a way that works for both of them. That's why
placing const data in flash on an AVR is non-conforming. ImageCraft,
whose compiler does place "const" in flash, makes no claims to the
contrary - they view it as a reasonable compromise that gives most users
the code they want in most cases, while keeping code neat and readable.
gcc-avr uses macros and attributes for flash, so that their "const" is
standard, and IAR uses the extra non-standard keyword "flash".

>> I suppose an avr compiler could get round this by using three-byte
>> pointers, but that would be somewhat inefficient.
>>
>> David



Relevant Pages

  • Re: Bug found in GCC-AVR/ AVRStudio
    ... I tell the linker to put const ... and how you use the linker. ... It is also valid to cast a non-const item (or pointer to ... default linker arrangement would be to put the "const" section in flash. ...
    (comp.arch.embedded)
  • Re: addind 500 users to a domain
    ... Const DomName = "Domein.nl" ... >> nifty little script that could do that in a flash. ... > for file format information. ...
    (microsoft.public.windows.server.setup)
  • Re: AVR Harvard architecture -- worst of both worlds?
    ... The only two problems with constants in flash are the awkward syntax, and for pointers. ... It is also inconsistent between different compilers for the same target. ...
    (comp.arch.embedded)
  • Re: Is this legal ?
    ... >> to be followed again if the compiler can't guarantee that nothing that ... >address of an object into a pointer to const type version, ... to change it (by casting away const from a pointer to it, ...
    (comp.lang.c)
  • Re: Why is the kfree() argument const?
    ... is there any reason why kfreetakes a const pointer just to degrade it ... In the particular case of kfree(), the pointer argument *should* be const, ... If a struct has a constant pointer to it, ...
    (Linux-Kernel)