Bug found in GCC-AVR/ AVRStudio

Do you have a question? Post it now! No Registration Necessary

Translate This Thread From English to

Threaded View
Hi,

I am using WinAVR-20040720 and AVRStudio 4.10. I have global variable
definitions in main.c. One of which is

char version[10]="1.0";

However, the version becomes "", i.e., version[0]=0 when the program is
debugged and the variable is watched.
Do anyone encounter similar problem? Thanks!


Re: Bug found in GCC-AVR/ AVRStudio
Quoted text here. Click to load it

This sounds more like an issue with the startup code. What happens if
you declare it as const char instead?


Re: Bug found in GCC-AVR/ AVRStudio
Same problem exists. Actually I tried const char firstly, but GCC
seemed to regard it as ram data.


Re: Bug found in GCC-AVR/ AVRStudio
Has also tried avrstudio 4.11 beta and the problem still exists.


Re: Bug found in GCC-AVR/ AVRStudio

Quoted text here. Click to load it

const data *is* ram data.  C does not have real constants - the term
"const" is only a hint to the compiler that you probably won't change it,
unless you really mean it.  So compilers that put "const" data into flash
are breaking the C standard (not necessarily a bad idea - but gcc doesn't
like to break the standard).  If you read the avrlibc documentation,
you'll find how to put strings in flash.


Re: Bug found in GCC-AVR/ AVRStudio

Quoted text here. Click to load it

Not in my systems it isn't.  I tell the linker to put const
data in ROM along with the code.

Quoted text here. Click to load it

gcc puts const data into seperate sections.  The linker puts
them into RAM vs. flash vs. whatever.

Quoted text here. Click to load it

--
Grant Edwards                   grante             Yow!  Are you selling NYLON
                                  at               OIL WELLS?? If so, we can
We've slightly trimmed the long signature. Click to see the full one.
Re: Bug found in GCC-AVR/ AVRStudio

Quoted text here. Click to load it

Won't help you on an AVR.  Harvard architecture.  The compiler has to
know the data is in ROM (Flash), or it will just read RAM.

Avr-gcc has some elaborate macros to help you out, e.g. (untested)

   #include <avr/pgmspace.h>

   const char my_string[] PROGMEM = "Hello World";
   char c;
   int i;

   c = pgm_read_byte(my_string);
   for (i=0; c; c=pgm_read_byte(my_string+(i++)))
      putchar(c);

PROGMEM expands into an __attribute__, and pgm_read_byte into in-line
assembly.

Some other compilers have memory space specifiers as a language
extension:

   flash char my_string[] = "Hello World";

But (at least with the ones I'm familiar with) you either have to call
special library functions (putsf vs. puts) or copy the data into RAM.

Regards,
        
                               -=Dave
--
Change is inevitable, progress is not.

Re: Bug found in GCC-AVR/ AVRStudio

Quoted text here. Click to load it

That's up to you, and how you use the linker.  The point is that C does
not enforce this, and it is valid to cast a "const" item to non-const and
then change it.  It is also valid to cast a non-const item (or pointer to
a non-const) to a const item (or pointer to a const) and use it.  On a
system with a single memory space (such as an msp430), the most sensible
default linker arrangement would be to put the "const" section in flash.
Casting a const to a non-const and changing it will then compile, but
simply won't work at run-time, while casting non-consts to consts will
work.  In practice, this will be fine for all but the most perverse
programmers.  However, if you really want to, you are free to link the
const section into ram and copy over the initial values on startup.  On a
system such as the avr, which has seperate memory spaces, this is exactly
what the compiler (and linker) *must* do, to conform with C standards,
since code generated to read data from ram would not be able to read data
in flash.

Quoted text here. Click to load it


Re: Bug found in GCC-AVR/ AVRStudio

Quoted text here. Click to load it

I've now been corrected - casting a const to a non-const is not legal C.

Quoted text here. Click to load it


Re: Bug found in GCC-AVR/ AVRStudio
snipped-for-privacy@westcontrol.removethis.com says...
Quoted text here. Click to load it

I don't believe so.  AFAIR the meaning of const in C is (more or less)
"it is forbidden to write to this".  The compiler/linker is free to place
that whereever suits them.

You may be thinking of strings like "hello" which are (again AFAIR) not
const.  But if declare something as

const int u = 9;
const char fg[] = "hello";

you get two items that are unwriteable and the compiler is free to place
them in readonly memory.

If you do this, however,

char * ty = "hello";

however ty points to a modifiable string.  Personnally I'd consider that
broken and rap the knuckles of any developer that proposed using it but
that's another issue.

Robert


Re: Bug found in GCC-AVR/ AVRStudio

Quoted text here. Click to load it

K&R second edition agress with you on this, although it does leave it up
to the implementation as to what happens if you do attempt to modify a
const.

Quoted text here. Click to load it

Well, given that no const modifier was used in this example...

If you meant:

const char * ty = "hello";

then, the pointer ty should be unmodifiable, whereas what it points at is
free to be modified as I recall.

--
Richard

Re: Bug found in GCC-AVR/ AVRStudio
snipped-for-privacy@netscape.net says...
Quoted text here. Click to load it

No, I meant what a wrote (suprisingly enough).  A modifiable pointer to
a modifiable string.  That construct is I suspect the reason strings are
not const (too many warning messages in compiling old programs that don't
use const).

Robert

Re: Bug found in GCC-AVR/ AVRStudio
On Mon, 17 Jan 2005 13:25:33 -0500, R Adsett

Quoted text here. Click to load it

Your first two examples are correct, but this last one is wrong.  The
pointer 'ty' is initialized with the address of a string literal.  The
type of a string literal in C is array of char (not array of const
char as it is in C++), but paragraph 6 of section 6.4.5 "String
literals" of the C standard specifically states that attempts to
modify a string literal cause undefined behavior.

Quoted text here. Click to load it

See also this question/answer from the comp.lang.c FAQ:

16.6 Why does the code "char *p = "hello, world!"; p[0] = 'H';" crash?
http://www.eskimo.com/~scs/C-faq/q16.6.html

--
Jack Klein
Home: http://JK-Technology.Com
We've slightly trimmed the long signature. Click to see the full one.
Re: Bug found in GCC-AVR/ AVRStudio
snipped-for-privacy@spamcop.net says...
Quoted text here. Click to load it

Yep, I didn't say it made sense.  It really was the type I was referring
to.  The fact that the literal is a plain char type ( and not a const)
implies that it is writeable.  The fact that it isn't, is shall we say,
counter-intuitive.  It's a bit of the past hanging around though.

A good lint will catch this but only to so many levels of indirection.  
At some point they get lost.

And you are of course right, you aren't supposed to write to the literal.  

Robert



Re: Bug found in GCC-AVR/ AVRStudio
snipped-for-privacy@junk.aeolusdevelopment.cm says...
Quoted text here. Click to load it

Hmm, that sounds a little petulant.

Quoted text here. Click to load it

This should really be the core of the response.

Robert

Re: Bug found in GCC-AVR/ AVRStudio
On Mon, 17 Jan 2005 23:48:38 -0500, R Adsett

Quoted text here. Click to load it

There's a very simple reason for this.  String literals were part of
the C language a good 15 years before the 1989 standard added the
'const' keyword, so that was 15 years worth of existing code that
would have been broken.

In fact, even in C++ where string literals do have the type array of
const char, they break the type system and allow the address of a
string literal to be assigned to a pointer to mutable char, just
because there is so much existing code.

Quoted text here. Click to load it

Someday somebody will invent the perfect computer programming
language.  It might be you.  For sure, I've given up on the idea that
it will be me!

--
Jack Klein
Home: http://JK-Technology.Com
We've slightly trimmed the long signature. Click to see the full one.
Re: Bug found in GCC-AVR/ AVRStudio
snipped-for-privacy@spamcop.net says...
Quoted text here. Click to load it

Nah, I'd probably do something silly like re-invent APL.

Robert

Re: Bug found in GCC-AVR/ AVRStudio
Quoted text here. Click to load it

Yep - the number 1 write-only language.

--

Tauno Voipio
tauno voipio (at) iki fi


Re: Bug found in GCC-AVR/ AVRStudio
On Mon, 17 Jan 2005 08:36:51 +0100, David

Quoted text here. Click to load it

You are absolutely wrong about what the C standard does and does not
specify.

You are right about the fact that C does not guarantee that any object
will be stored in memory that is physically unwriteable by a program.

But you are wrong about the fact that compilers that put "const" data
into flash are breaking the C standard.  Far from it.  In fact, a
strictly conforming C program can never tell if objects defined with
the const qualifier are in read-write or read-only memory.  The moment
a C program attempts to modify any object defined with the const
qualifier, it ceases to be a strictly conforming C program, or even a
legal C program at all.

Not only does this apply to objects defined const, it applies to
string literals as well, although this does not apply to the OP's
original post.

Quoted text here. Click to load it

This definition, in the OP's post, defines an array of 10 plain old
ordinary modifiable characters, initializes the first 3 of them with
'1', '.', and '0', and initializes the last 7 of them with ''.  If
the tool set, perhaps at the link stage, could determine that the
program never modified this array, it could place it in read-only
memory.  If it could not verify that, and most tool sets can't, then
it must be placed in RAM.

On the other hand, these definitions:

char *version = "1.0";
const int cint = 42;

...define data objects that can be placed in memory that the program
cannot modify, like ROM, EPROM or flash.  The int object because it is
defined const, and the string literal because the C standard
specifically states that attempting to modify a string literal
produces undefined behavior.

As others have pointed out in this thread, compilers generally put
data like my two examples above into a specific segment, often with a
name like "const" or ".const".  It is up to later steps, such as a
linker or loader, to decide where in physical memory that segment is
located.

But any C program which can tell in any way whether 'version' or
'cint' above are in read-only or read-write memory is not a legal C
program.

--
Jack Klein
Home: http://JK-Technology.Com
We've slightly trimmed the long signature. Click to see the full one.
Re: Bug found in GCC-AVR/ AVRStudio

Quoted text here. Click to load it

In the face of such opposition, I looked up some references - you are
right.  The standard says that the effect of code such as:

    const int i = 100;
    *((int *) &i) = 101;

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 ?


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.

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

David


Quoted text here. Click to load it


Site Timeline