Hello All,
Some C questions were bugging me from quite some time. Any answers!
please share.
1. GIven an .EXE is there a way to find how many global varibale it
uses?
2. Given 2 Strings char *str1 = "JHONSON";
char *str2 = "O";
what is the fastest way to remove all occurences of letter O from str1.
3. Given 2 STACKS, how to implement a QUEUE?
4. what are MAK files? where are they used (Not quite C related but
just in case.)
5. what does .OBJ files contains?
6. how does DLL link on runtime?
7. what is ELF format?
Best Regards,
#define
|
|
0
|
|
|
|
Reply
|
u4karsh (9)
|
12/27/2005 6:10:58 PM |
|
#define <u4karsh@gmail.com> wrote:
> Hello All,
>
> Some C questions were bugging me from quite some time. Any answers!
> please share.
Well, you've posted it twice, is your prof going to fail you twice?
It's the season of goodwill to all men - except people who are failing
100-level CS courses and trying to beg for answers on Usenet. They
*deserve* to go to the wall.
pete
--
pete@fenelon.com "there's no room for enigmas in built-up areas" - HMHB.
|
|
0
|
|
|
|
Reply
|
pete6 (288)
|
12/27/2005 6:29:38 PM
|
|
"#define" <u4karsh@gmail.com> wrote in message
news:1135707058.003352.250540@g44g2000cwa.googlegroups.com...
> Hello All,
>
> Some C questions were bugging me from quite some time. Any answers!
> please share.
>
> 2. Given 2 Strings char *str1 = "JHONSON";
> char *str2 = "O";
>
> what is the fastest way to remove all occurences of letter O from str1.
>
str1[0] = '\0';
Rufus
|
|
0
|
|
|
|
Reply
|
nospam21 (11322)
|
1/12/2006 10:26:40 PM
|
|
Rufus V. Smith wrote:
> "#define" <u4karsh@gmail.com> wrote in message
>>
>> Some C questions were bugging me from quite some time. Any answers!
>> please share.
>>
>> 2. Given 2 Strings char *str1 = "JHONSON";
>> char *str2 = "O";
>>
>> what is the fastest way to remove all occurences of letter O
>> from str1.
>
> str1[0] = '\0';
Bzzt - WRONG. str1 contains a pointer to a non-modifiable string
(which may well reside in ROM). str1 itself contains no letter O.
Thus the only way is:
str1 = "JHNSN";
Things would be different if the original declaration was:
char str1[] = "JHONSON";
which would have initialized a character array to a C string.
--
"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
More details at: <http://cfaj.freeshell.org/google/>
|
|
0
|
|
|
|
Reply
|
cbfalconer (19183)
|
1/12/2006 11:01:01 PM
|
|
Chuck F. wrote:
> Rufus V. Smith wrote:
>> "#define" <u4karsh@gmail.com> wrote in message
>>>
>>> Some C questions were bugging me from quite some time. Any answers!
>>> please share.
>>>
>>> 2. Given 2 Strings char *str1 = "JHONSON";
>>> char *str2 = "O";
>>>
>>> what is the fastest way to remove all occurences of letter O
>>> from str1.
>>
>> str1[0] = '\0';
>
> Bzzt - WRONG. str1 contains a pointer to a non-modifiable string (which
> may well reside in ROM). str1 itself contains no letter O. Thus the
> only way is:
>
> str1 = "JHNSN";
>
> Things would be different if the original declaration was:
>
> char str1[] = "JHONSON";
>
> which would have initialized a character array to a C string.
>
Or Not... this type of thing can be very compiler dependent!
Paul
|
|
0
|
|
|
|
Reply
|
nospam3198 (106)
|
1/13/2006 1:23:43 AM
|
|
Paul Whitfield wrote:
> Chuck F. wrote:
>> Rufus V. Smith wrote:
>>> "#define" <u4karsh@gmail.com> wrote in message
>>>>
>>>> Some C questions were bugging me from quite some time. Any answers!
>>>> please share.
>>>>
>>>> 2. Given 2 Strings char *str1 = "JHONSON";
>>>> char *str2 = "O";
>>>>
>>>> what is the fastest way to remove all occurences of letter O
>>>> from str1.
>>>
>>> str1[0] = '\0';
>>
>> Bzzt - WRONG. str1 contains a pointer to a non-modifiable
>> string (which may well reside in ROM). str1 itself contains no
>> letter O. Thus the only way is:
>>
>> str1 = "JHNSN";
>>
>> Things would be different if the original declaration was:
>>
>> char str1[] = "JHONSON";
>>
>> which would have initialized a character array to a C string.
>>
> Or Not... this type of thing can be very compiler dependent!
No. The behaviour is spelled out in the C standard.
--
"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
More details at: <http://cfaj.freeshell.org/google/>
|
|
0
|
|
|
|
Reply
|
cbfalconer (19183)
|
1/13/2006 1:40:18 AM
|
|
Chuck F. wrote:
> Paul Whitfield wrote:
>> Chuck F. wrote:
>>> Rufus V. Smith wrote:
>>>> "#define" <u4karsh@gmail.com> wrote in message
>>>>>
>>>>> Some C questions were bugging me from quite some time. Any answers!
>>>>> please share.
>>>>>
>>>>> 2. Given 2 Strings char *str1 = "JHONSON";
>>>>> char *str2 = "O";
>>>>>
>>>>> what is the fastest way to remove all occurences of letter O
>>>>> from str1.
>>>>
>>>> str1[0] = '\0';
>>>
>>> Bzzt - WRONG. str1 contains a pointer to a non-modifiable string
>>> (which may well reside in ROM). str1 itself contains no
>>> letter O. Thus the only way is:
>>>
>>> str1 = "JHNSN";
>>>
>>> Things would be different if the original declaration was:
>>>
>>> char str1[] = "JHONSON";
>>>
>>> which would have initialized a character array to a C string.
>>>
>> Or Not... this type of thing can be very compiler dependent!
>
> No. The behaviour is spelled out in the C standard.
From My K&R (closest thing I have handy to the actual standard
it says:
"A Character array whose members are initialised with a string,
its size includes the null terminating character".
On a host system with a modern compiler you are 100% correct.
On an 8-bit embedded systems... I have seen compilers
that will store the string in ROM. All the while
claiming to be ANSI Compliant!
The problem is to do this properly on an embedded
system the compiler has to actually copy the
data from ROM to the string.
Regards
Paul
|
|
0
|
|
|
|
Reply
|
nospam3198 (106)
|
1/13/2006 2:07:51 AM
|
|
Paul Whitfield <NoSpam@iinet.net.au> wrote:
> Chuck F. wrote:
>> Paul Whitfield wrote:
>>> Chuck F. wrote:
>>>>
>>>>> char *str1 = "JOHNSON";
>>>>>
>>>> Bzzt - WRONG. str1 contains a pointer to a non-modifiable string
>>>> (which may well reside in ROM). str1 itself contains no
>>>> letter O. Thus the only way is:
>>>>
>>>> str1 = "JHNSN";
>>>>
>>>> Things would be different if the original declaration was:
>>>>
>>>> char str1[] = "JHONSON";
>>>>
>>>> which would have initialized a character array to a C string.
>>>>
>>> Or Not... this type of thing can be very compiler dependent!
>>
>> No. The behaviour is spelled out in the C standard.
>
> From My K&R (closest thing I have handy to the actual standard
> it says:
>
> "A Character array whose members are initialised with a string,
> its size includes the null terminating character".
>
> On a host system with a modern compiler you are 100% correct.
>
> On an 8-bit embedded systems... I have seen compilers
> that will store the string in ROM. All the while
> claiming to be ANSI Compliant!
I would say those compilers are just broken.
> The problem is to do this properly on an embedded
> system the compiler has to actually copy the
> data from ROM to the string.
And that is *exactly* what it should do, but why is that a problem ?
It is not any different then declaring and initializing an int, for
example :
int a = 5;
int b[] = { 1, 2, 3 };
char msg[] = "Hello";
--
:wq
^X^Cy^K^X^C^C^C^C
|
|
0
|
|
|
|
Reply
|
usenet124 (276)
|
1/13/2006 8:56:57 AM
|
|
> "#define" <u4karsh@gmail.com> wrote in message
> news:1135707058.003352.250540@g44g2000cwa.googlegroups.com...
>> Hello All,
>>
>> Some C questions were bugging me from quite some time. Any answers!
>> please share.
>>
>> 2. Given 2 Strings char *str1 = "JHONSON";
>> char *str2 = "O";
>>
>> what is the fastest way to remove all occurences of letter O from str1.
>>
The fastest way is to do it is in assembler not C.
Ian
|
|
0
|
|
|
|
Reply
|
ruffrecords2 (612)
|
1/13/2006 11:34:23 AM
|
|
Ico wrote:
> Paul Whitfield <NoSpam@iinet.net.au> wrote:
>
>> On an 8-bit embedded systems... I have seen compilers
>> that will store the string in ROM. All the while
>> claiming to be ANSI Compliant!
>
> I would say those compilers are just broken.
>
A yeah, very helpful - tail wagging the dog methinks.
>> The problem is to do this properly on an embedded
>> system the compiler has to actually copy the
>> data from ROM to the string.
>
> And that is *exactly* what it should do, but why is that a problem ?
You really don't have a clue about managing scarce resources do you?
Ian
|
|
0
|
|
|
|
Reply
|
ruffrecords2 (612)
|
1/13/2006 11:36:39 AM
|
|
Ian Bell <ruffrecords@yahoo.com> wrote:
> Ico wrote:
>
>> Paul Whitfield <NoSpam@iinet.net.au> wrote:
>>
>>> On an 8-bit embedded systems... I have seen compilers
>>> that will store the string in ROM. All the while
>>> claiming to be ANSI Compliant!
>>
>> I would say those compilers are just broken.
>
> A yeah, very helpful - tail wagging the dog methinks.
I don't see how I could be helpful at all in this case. I believe that
having a compiler that by default stores
char msg[] = "Hello";
into read only memory really *is* broken, and there is nothing I can do
about that by writing in a newsgroup, is there ?
>>> The problem is to do this properly on an embedded system the
>>> compiler has to actually copy the data from ROM to the string.
>>
>> And that is *exactly* what it should do, but why is that a problem ?
I forgot to mention that this is not a job for the compiler, but for the
C startup code, ofcourse.
> You really don't have a clue about managing scarce resources do you?
I may not know all about it, but while spending my last few years coding
C and assembly on tiny embedded platforms, I might have learned
*something* about scarse resources, I hope. Apart from that, I do not
understand what broken compilers and not having a clue about scarce
resources have to do with each other ?
Since I am not a C expert by any means, I would like to invite you to
continue this discussion on comp.lang.c; I assume there are people there
who can shed some light on this issue.
Ico
--
:wq
^X^Cy^K^X^C^C^C^C
|
|
0
|
|
|
|
Reply
|
usenet124 (276)
|
1/13/2006 12:07:59 PM
|
|
Ico wrote:
>
> I don't see how I could be helpful at all in this case. I believe that
> having a compiler that by default stores
>
> char msg[] = "Hello";
>
> into read only memory really *is* broken, and there is nothing I can do
> about that by writing in a newsgroup, is there ?
>
You miss the point. Just because a compiler is not ANSI compliant does not
mean it is broken. C was never designed to run on ROM based systems. The
'problems' only occur when people forget this.
>>>> The problem is to do this properly on an embedded system the
>>>> compiler has to actually copy the data from ROM to the string.
>>>
>>> And that is *exactly* what it should do, but why is that a problem ?
>
> I forgot to mention that this is not a job for the compiler, but for the
> C startup code, ofcourse.
>
>> You really don't have a clue about managing scarce resources do you?
>
> I may not know all about it, but while spending my last few years coding
> C and assembly on tiny embedded platforms, I might have learned
> *something* about scarse resources, I hope. Apart from that, I do not
> understand what broken compilers and not having a clue about scarce
> resources have to do with each other ?
The you would know that copying a string from ROM to the string (RAM) is a
waste of precious rsources.
>
> Since I am not a C expert by any means, I would like to invite you to
> continue this discussion on comp.lang.c; I assume there are people there
> who can shed some light on this issue.
>
Again you miss the point. This is not a compiler or C question/problem it is
about using them on ROM based systems.
Ian
|
|
0
|
|
|
|
Reply
|
ruffrecords2 (612)
|
1/13/2006 1:54:25 PM
|
|
Hi Ian,
Ian Bell wrote:
> >> what is the fastest way to remove all occurences of letter O from
> str1.
> > >
>
> The fastest way is to do it is in assembler not C.
If that is true, you should look for a compiler alternative :-).
Regards, Kurt
--
Kurt Harders
PiN -Pr�senz im Netz GITmbH
mailto:news@kurt-harders.de
http://www.pin-gmbh.com
|
|
0
|
|
|
|
Reply
|
news8690 (21)
|
1/13/2006 2:06:35 PM
|
|
Ico wrote:
>
> I don't see how I could be helpful at all in this case. I believe that
> having a compiler that by default stores
>
> char msg[] = "Hello";
>
> into read only memory really *is* broken, and there is nothing I can do
> about that by writing in a newsgroup, is there ?
The trouble is that the standard doesn't take the requirements of small
embedded systems into account. Most compilers (for microcontrollers)
will create the string as an initialised variable in RAM. To force it
into another space, different compilers come up with different
constructs. Some use 'const' as a marker that the string is to be in
ROM. Others add extra keywords like 'code'. Others still put all
initialised strings into ROM unless you tell them not to. And it's a
bugger when porting code.
I think we are simply below the radar of the exalted creatures who dwell
in bliss on the standards committees.
Paul Burke
|
|
0
|
|
|
|
Reply
|
paul355 (411)
|
1/13/2006 2:24:44 PM
|
|
Ian Bell <ruffrecords@yahoo.com> wrote:
> Ico wrote:
>
>> I don't see how I could be helpful at all in this case. I believe that
>> having a compiler that by default stores
>>
>> char msg[] = "Hello";
>>
>> into read only memory really *is* broken, and there is nothing I can do
>> about that by writing in a newsgroup, is there ?
>
> You miss the point. Just because a compiler is not ANSI compliant does not
> mean it is broken.
Paul Whitfield stated in his original message :
>>> I have seen compilers that will store the string in ROM. All the
>>> while claiming to be ANSI Compliant!
In this context, I think it is safe to consider this compiler broken.
> C was never designed to run on ROM based systems. The 'problems' only
> occur when people forget this.
>
>>>>> The problem is to do this properly on an embedded system the
>>>>> compiler has to actually copy the data from ROM to the string.
>>>>
>>>> And that is *exactly* what it should do, but why is that a problem ?
>>
>> I forgot to mention that this is not a job for the compiler, but for the
>> C startup code, ofcourse.
>>
>>> You really don't have a clue about managing scarce resources do you?
>>
>> I may not know all about it, but while spending my last few years coding
>> C and assembly on tiny embedded platforms, I might have learned
>> *something* about scarse resources, I hope. Apart from that, I do not
>> understand what broken compilers and not having a clue about scarce
>> resources have to do with each other ?
>
> Then you would know that copying a string from ROM to the string (RAM) is a
> waste of precious rsources.
Yes, ofcourse I know. So that is why I ask my compiler *not* to do that
if I need a constant instead of a variable. The exact procedure is
somewhat compiler- and platform-specific. Usually, using 'const' is
enough, although I have used compilers which need attributes or pragma's
for that.
Still, my point is: when I declare an array the normal way ( char msg[]
= "Hello"; ) , I would never, ever want the compiler to put that in ROM.
If a compiler *does* put that in read only memory, and claims to be ANSI
compatible, it posesses a certain amount of faultiness. I call it 'broken'
>> Since I am not a C expert by any means, I would like to invite you to
>> continue this discussion on comp.lang.c; I assume there are people there
>> who can shed some light on this issue.
>
> Again you miss the point. This is not a compiler or C question/problem it is
> about using them on ROM based systems.
My apologies for for missing the point, but I was assuming we were
discussing a C compiler which was claimed to be ANSI compatible. It
seems we were not talking about the same subject, so let's drop this
conversation for now.
Ico
--
:wq
^X^Cy^K^X^C^C^C^C
|
|
0
|
|
|
|
Reply
|
usenet124 (276)
|
1/13/2006 2:26:02 PM
|
|
On 12/01/2006 the venerable Chuck F. etched in runes:
> Rufus V. Smith wrote:
> >"#define" <u4karsh@gmail.com> wrote in message
> > >
> > > Some C questions were bugging me from quite some time. Any answers!
> > > please share.
> > >
> > > 2. Given 2 Strings char *str1 = "JHONSON";
> >> char *str2 = "O";
> > >
> > > what is the fastest way to remove all occurences of letter O
> > > from str1.
> >
> > str1[0] = '\0';
>
> Bzzt - WRONG. str1 contains a pointer to a non-modifiable string (which may well reside in ROM).
> str1 itself contains no letter O. Thus the only way is:
>
> str1 = "JHNSN";
>
> Things would be different if the original declaration was:
>
> char str1[] = "JHONSON";
>
> which would have initialized a character array to a C string.
Bzzzzt - WRONG.
A pointer to non-modifiable string would be declared as
const char *str1 = "JHONSON";
The two declarations:
char str1* = "JHONSON";
and
char str2[] = "JHONSON";
both allocate space for a modifiable string. The difference being that the first one also creates a
pointer to that string.
--
John B
|
|
0
|
|
|
|
Reply
|
spamj_baraclough (152)
|
1/13/2006 2:27:32 PM
|
|
"John B" <spamj_baraclough@blockerzetnet.co.uk> wrote in message
news:43c7b8d3$0$819$4c56ba96@master.news.zetnet.net...
> On 12/01/2006 the venerable Chuck F. etched in runes:
>
> > Rufus V. Smith wrote:
> > >"#define" <u4karsh@gmail.com> wrote in message
> > > >
> > > > Some C questions were bugging me from quite some time. Any answers!
> > > > please share.
> > > >
> > > > 2. Given 2 Strings char *str1 = "JHONSON";
> > >> char *str2 = "O";
> > > >
> > > > what is the fastest way to remove all occurences of letter O
> > > > from str1.
> > >
> > > str1[0] = '\0';
> >
> > Bzzt - WRONG. str1 contains a pointer to a non-modifiable string (which
may well reside in ROM).
> > str1 itself contains no letter O. Thus the only way is:
> >
> > str1 = "JHNSN";
> >
> > Things would be different if the original declaration was:
> >
> > char str1[] = "JHONSON";
> >
> > which would have initialized a character array to a C string.
>
> Bzzzzt - WRONG.
>
> A pointer to non-modifiable string would be declared as
>
> const char *str1 = "JHONSON";
>
>
> The two declarations:
>
> char str1* = "JHONSON";
>
> and
>
> char str2[] = "JHONSON";
>
> both allocate space for a modifiable string. The difference being that the
first one also creates a
> pointer to that string.
Isn't str2 also a pointer?
BTW, I will admit a recurring problem with understanding the nuances of C
pointers.
|
|
0
|
|
|
|
Reply
|
rphenry (125)
|
1/13/2006 3:16:56 PM
|
|
Ian Bell wrote:
> Ico wrote:
>> Paul Whitfield <NoSpam@iinet.net.au> wrote:
>>
>>> On an 8-bit embedded systems... I have seen compilers that
>>> will store the string in ROM. All the while claiming to be
>>> ANSI Compliant!
>>
>> I would say those compilers are just broken.
>
> A yeah, very helpful - tail wagging the dog methinks.
>
>>> The problem is to do this properly on an embedded system the
>>> compiler has to actually copy the data from ROM to the
>>> string.
>>
>> And that is *exactly* what it should do, but why is that a
>> problem ?
>
> You really don't have a clue about managing scarce resources do
> you?
I think you have missed the entire point. Something declared as:
char *s = "string";
declares a non-writeable "string" which may be in rom. However
char s[] = "string";
declares a 7 byte char array, which must be writable, and is
initialized to contain "string\0". Here, in most cases, the value
of s is passed as a pointer to the first char of "string".
As a result, a function
T foo(char *stg) {...}
called by
foo(s);
will receive the same _value_ in the parameter stg for either
original declaration. However in one case *stg is writable, in the
other it is not.
gcc allows the 'char *s = "string"' to imply const char. This is
helpful in tracking down bugs if you use const correctly elsewhere.
--
"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
More details at: <http://cfaj.freeshell.org/google/>
|
|
0
|
|
|
|
Reply
|
cbfalconer (19183)
|
1/13/2006 3:50:27 PM
|
|
John B <spamj_baraclough@blockerzetnet.co.uk> wrote:
> A pointer to non-modifiable string would be declared as
> const char *str1 = "JHONSON";
There are good arguments that that's what it _should_ be like, but it
isn't.
> The two declarations:
> char str1* = "JHONSON";
> and
> char str2[] = "JHONSON";
> both allocate space for a modifiable string.
Completely wrong, for two reasons.
1) A typo: the first one has to read
char *str1 = "JHONSON"
2) Incorrect ideas about C. The string allocated by this (fixed)
declaration is *not* modifiable. Any program trying to write to
str1[i] would be broken.
Some C platforms will indeed keep string literals in modifiable
storage. But the language definition explicitly allows them to be in
read-only storage, and that means all programs assuming otherwise are
broken. They cause undefined behaviour.
This is all for hysterical raisins. From an abstract point of view,
the type of string literals _should_ obviously be "array of const
char", which would mean
char *str1 = "JHONSON"
would trigger a warning about mixing const and non-const. But it
isn't. That's because there was no "const" in the original language,
and by the time it was added in a reliable way, it was way past too
late to change that.
--
Hans-Bernhard Broeker (broeker@physik.rwth-aachen.de)
Even if all the snow were burnt, ashes would remain.
|
|
0
|
|
|
|
Reply
|
broeker (1253)
|
1/13/2006 3:56:25 PM
|
|
John B wrote:
>
.... snip ...
>
> A pointer to non-modifiable string would be declared as
>
> const char *str1 = "JHONSON";
>
> The two declarations:
>
> char str1* = "JHONSON";
you mean "char *str1 = ..."
>
> and
>
> char str2[] = "JHONSON";
>
> both allocate space for a modifiable string. The difference
> being that the first one also creates a pointer to that string.
Not so. I just wrote an explanation of the difference in this
thread. The char * declaration _MAY_ create a modifiable string,
but need not. This allows multiple such declarations to point to
the same actual string, if the compiler so chooses.
--
"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
More details at: <http://cfaj.freeshell.org/google/>
|
|
0
|
|
|
|
Reply
|
cbfalconer (19183)
|
1/13/2006 3:56:54 PM
|
|
On Fri, 13 Jan 2006 07:16:56 -0800 in comp.arch.embedded, "Richard
Henry" <rphenry@home.com> wrote:
>
>"John B" <spamj_baraclough@blockerzetnet.co.uk> wrote in message
>news:43c7b8d3$0$819$4c56ba96@master.news.zetnet.net...
>> On 12/01/2006 the venerable Chuck F. etched in runes:
[...]
>> The two declarations:
>>
>> char str1* = "JHONSON";
>>
>> and
>>
>> char str2[] = "JHONSON";
>>
>> both allocate space for a modifiable string. The difference being that the
>first one also creates a
>> pointer to that string.
>
>Isn't str2 also a pointer?
No.
Repeat after me: "Arrays are not pointers. Pointers are not arrays."
Despite what you may have been told.
A pointer is an object that references some other object.
An array is a group of contiguously allocated objects of the same
type.
(This is the important bit) The unadorned name of an array devolves
into a pointer to the first element of that array. Sort of like a
compile-time constant.
One point of confusion is the mechanism of array indexing. The syntax
"a[i]" has *exactly* the same meaning as "(*a + i)" whether a is a
pointer or array. So given the declarations above, str1[0] == 'J' ==
str2[0].
Another is the syntax for passing an array as a parameter to a
function. Thus "Fn(str1);" looks to be much the same as "Fn(str2);"
but the actual semantics are a bit different. Inside the function
itself, of course, the parameter is the same in either case.
>
>BTW, I will admit a recurring problem with understanding the nuances of C
>pointers.
>
Peter van der Linden's "Expert C Programming: Deep C Secrets" has one
or two excellent chapters on the differences between arrays and
pointers (as well as sections on understanding and contruction C
declarations, and other topics introductory books are to timid to
tackle). Somewhat dated (it was written about a dozen years ago), but
very readable and recommended. You don't read it because you're an
expert already, you read it to become expert...
Regards,
-=Dave
--
Change is inevitable, progress is not.
|
|
0
|
|
|
|
Reply
|
iddw (679)
|
1/13/2006 4:47:45 PM
|
|
>Ico wrote:
>> I don't see how I could be helpful at all in this case. I believe that
>> having a compiler that by default stores
>>
>> char msg[] = "Hello";
>>
>> into read only memory really *is* broken, and there is nothing I can do
>> about that by writing in a newsgroup, is there ?
In article <dq8bcf$k8p$1@slavica.ukpost.com>
Ian Bell <ruffrecords@yahoo.com> wrote:
>... Just because a compiler is not ANSI compliant does not
>mean it is broken.
If it *claims* to be ANSI-compliant, but is not, *something* is
broken: either the compler itself, or the claim. The array "msg"
above is a modifiable lvalue and must not be stored in ROM.
Note, however, that if we write this instead:
char *msg = "Hello";
the anonymous array created by the string literal is *not* modifiable
and *may* (and indeed should by default) by stored in ROM.
(Pointers are not arrays; see <http://www.c-faq.com/aryptr/index.html>).
>C was never designed to run on ROM based systems.
It is true that C was not originally designed for ROMs, but the
original ANSI Standard C, developed back in the 1980s, had input
from embedded compiler folks and is quite suited to ROMable code.
A const-qualified object may (and often[%] should) go directly into
a ROM section. Objects that are not const-qualified must be stored
in read/write memory, with the exception of the contents of string
literals.
[% Block-scope automatic objects that are const-qualified must
still behave in a stack-like manner, so unless the compiler can
prove that there is only one instance of that function active at
any point, or that all active instances never have their different
objects' addresses compared, the object itself cannot be shared,
so putting one (shared) instance in ROM would be wrong. For example,
consider the following -- rather bizarre -- function:
int f(const char *p) {
const char x = 'x';
if (p != NULL)
return p == &x;
return f(&x);
}
Here f(NULL) must return 0 (and indeed, so must f(&var) for any
suitable variable "var"). (If the object "x" is collapsed to a
single instance -- as if it had been declared:
static const char x = 'x';
-- then f(NULL) would actually return 1.) A sufficiently smart
compiler could replace the contents of f() with "return 0;" and
remove the variable x entirely, although I would be fairly surprised
to see a compiler do that.]
C99 adds anonymous structures and arrays, using a syntax that
resembles (but is not actually) a cast of a brace-enclosed sequence
of suitable values:
const int *p = (const int []){1, 2, 3};
and again the "const" qualifier allows a compiler to put the
object into ROM. Note that "p" itself must be in RAM, as it is not
itself const -- to put p in ROM use:
const int *const p = (const int []){1, 2, 3};
>The you would know that copying a string from ROM to the string (RAM)
>is a waste of precious rsources.
Unless, of course, the string must be modifiable:
char bootline[BOOTLINELENGTH] = "/ata0a/boot.img";
should not put the bootline array into ROM, but rather copy the
literal from ROM to the array -- roughly the equivalent of:
char bootline[BOOTLINELENGTH];
void part_of_startup(void) { /* or part of the function prologue if
the array is local to a function */
/* note: no need to include a \0 in the literal ... */
memcpy(bootline, (const char [15]){"/ata0a/boot.img"}, 15);
/* ... because we have to zero out the rest of the array */
memset(bootline + 15, 0, sizeof bootline - 15);
/* the above memset() can be part of a memset that zeros all
"bss"-like data, assuming of course that all-bytes-zero is
the correct machine-level representation for all the
zero-initialized "bss-like" objects in the image */
}
If the string has to be modifiable, and initialized data is placed
in ROM, you would have to write your own routine to initialize the
array, using at least as much of those "precious resources" anyway.
--
In-Real-Life: Chris Torek, Wind River Systems
Salt Lake City, UT, USA (40�39.22'N, 111�50.29'W) +1 801 277 2603
email: forget about it http://web.torek.net/torek/index.html
Reading email is like searching for food in the garbage, thanks to spammers.
|
|
0
|
|
|
|
Reply
|
nospam252 (1722)
|
1/13/2006 4:55:09 PM
|
|
"Dave Hansen" <iddw@hotmail.com> wrote in message
news:lglfs11e4ifgilnq2mh3d35ufjc8713mr2@4ax.com...
> On Fri, 13 Jan 2006 07:16:56 -0800 in comp.arch.embedded, "Richard
> Henry" <rphenry@home.com> wrote:
>
> >
> >"John B" <spamj_baraclough@blockerzetnet.co.uk> wrote in message
> >news:43c7b8d3$0$819$4c56ba96@master.news.zetnet.net...
> >> On 12/01/2006 the venerable Chuck F. etched in runes:
> [...]
> >> The two declarations:
> >>
> >> char str1* = "JHONSON";
> >>
> >> and
> >>
> >> char str2[] = "JHONSON";
> >>
> >> both allocate space for a modifiable string. The difference being that
the
> >first one also creates a
> >> pointer to that string.
> >
> >Isn't str2 also a pointer?
>
> No.
>
> Repeat after me: "Arrays are not pointers. Pointers are not arrays."
> Despite what you may have been told.
>
> A pointer is an object that references some other object.
>
> An array is a group of contiguously allocated objects of the same
> type.
>
> (This is the important bit) The unadorned name of an array devolves
> into a pointer to the first element of that array. Sort of like a
> compile-time constant.
>
> One point of confusion is the mechanism of array indexing. The syntax
> "a[i]" has *exactly* the same meaning as "(*a + i)" whether a is a
> pointer or array. So given the declarations above, str1[0] == 'J' ==
> str2[0].
>
> Another is the syntax for passing an array as a parameter to a
> function. Thus "Fn(str1);" looks to be much the same as "Fn(str2);"
> but the actual semantics are a bit different. Inside the function
> itself, of course, the parameter is the same in either case.
>
> >
> >BTW, I will admit a recurring problem with understanding the nuances of C
> >pointers.
> >
>
> Peter van der Linden's "Expert C Programming: Deep C Secrets" has one
> or two excellent chapters on the differences between arrays and
> pointers (as well as sections on understanding and contruction C
> declarations, and other topics introductory books are to timid to
> tackle). Somewhat dated (it was written about a dozen years ago), but
> very readable and recommended. You don't read it because you're an
> expert already, you read it to become expert...
I will defer to you knowledge of C pointers.
However, my confusion about them has only increased.
|
|
0
|
|
|
|
Reply
|
rphenry (125)
|
1/13/2006 6:50:47 PM
|
|
Paul Burke <paul@scazon.com> writes:
> Ico wrote:
>> I don't see how I could be helpful at all in this case. I believe that
>> having a compiler that by default stores
>> char msg[] = "Hello";
>> into read only memory really *is* broken, and there is nothing I
>> can do about that by writing in a newsgroup, is there ?
>
> The trouble is that the standard doesn't take the requirements of
> small embedded systems into account.
I don't see anything in your article that supports that statement.
> Most compilers (for
> microcontrollers) will create the string as an initialised variable in
> RAM.
Which is exactly what I'd expect.
> To force it into another space, different compilers come up with
> different constructs. Some use 'const' as a marker that the string is
> to be in ROM.
And that's perfectly appropriate. If it's declared 'const', any
attempt to modify it would invoke undefined behavior, so putting it in
ROM can't create problems for correct code.
> Others add extra keywords like 'code'.
That would break any programs that attempt to use 'code' as an
identifier (unless, for example, the keyword is recognized only after
a system-specific header is included), but otherwise it seems
innocuous enough. It makes sense if you want an explicit directive to
put a variable in a special memory segment (ROM or whatever), as
opposed to "const" which is merely a promise by the programmer not to
modify the variable.
> Others still put
> all initialised strings into ROM unless you tell them not to. And it's
> a bugger when porting code.
And that sounds like a serious problem. If I can't do the following:
char msg[] = "Hello";
msg[0] = 'h';
then I'm not using a conforming C compiler. There's nothing
inherently wrong with implementing a C-like language that doesn't
allow you to do this, of course, but it's not really C.
And unles I'm missing something, there's just no need for a compiler
to behave that way. If I want msg to be in ROM, I can just declare it
as const (or use whatever extension the compiler provides to force it
into ROM). You can do everything you need to do within the confines
of standard C.
> I think we are simply below the radar of the exalted creatures who
> dwell in bliss on the standards committees.
I don't think so; it seems more like certain compiler implementers are
ignoring the standard.
--
Keith Thompson (The_Other_Keith) kst-u@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
|
|
0
|
|
|
|
Reply
|
kst-u (21467)
|
1/13/2006 6:56:12 PM
|
|
On Fri, 13 Jan 2006 10:50:47 -0800, Richard Henry wrote:
> I will defer to you knowledge of C pointers.
>
> However, my confusion about them has only increased.
AHA! Breakthrough! Now you're getting it.
;)
Bob
|
|
0
|
|
|
|
Reply
|
roberts (35)
|
1/13/2006 7:07:02 PM
|
|
Richard Henry wrote:
> "John B" <spamj_baraclough@blockerzetnet.co.uk> wrote in message
> news:43c7b8d3$0$819$4c56ba96@master.news.zetnet.net...
>> The two declarations:
>>
>> char str1* = "JHONSON";
I'll assume that's supposed to be 'char *str1 = "JHONSON";'...
>> and
>>
>> char str2[] = "JHONSON";
>>
>> both allocate space for a modifiable string. The difference being that the
>> first one also creates a pointer to that string.
> Isn't str2 also a pointer?
Nope, it's an array. If it helps to make things clearer, sizeof(str1)
will be different than sizeof(str2). In particular:
sizeof(str1) == sizeof(char *)
and
sizeof(str2) == strlen(str2)+1
That should help make it clearer that str1 and str2 are different types.
If you were to give them names, str1's type would be "char *" and str2's
type might be "char[8]". One is a pointer and the other is an array.
That may not make much sense, but think for a moment about how an int
can be automatically converted to a float:
int i = 1;
float f = 3.14159;
printf ("%g", i + f);
What's going on here is that the compiler sees an expression where the
operator (in this case "+") has two arguments which are different types.
It then implicitly converts the integer into a floating point value
when generating the code that will correspond to that expression.
A similar thing happens when arrays are used where a pointer value is
needed. The compiler thinks "this isn't a pointer, but since it's an
array, I can create a pointer value from it".
Another way they differ, if I understand correctly is that this would
be legal:
str1 = (char *) "another string";
but this would not be:
str2 = (char *) "another string";
The reason is this: str1 is just a pointer, so it can take on any value.
But str2 is the array that contains { 'J', 'H', 'O', 'N', 'S', 'O', 'N', 0 },
and how are you supposed to assign a pointer to that?
- Logan
|
|
0
|
|
|
|
Reply
|
lshaw-usenet (926)
|
1/13/2006 7:12:20 PM
|
|
On Fri, 13 Jan 2006 10:47:45 -0600, Dave Hansen <iddw@hotmail.com>
wrote:
>"a[i]" has *exactly* the same meaning as "(*a + i)" whether a is a
>pointer or array.
You mean *((a)+(i)). Or perhaps more precisely, to capture usual
unary conversion rules, *((&a[0])+(i)).
Jon
|
|
0
|
|
|
|
Reply
|
jkirwan (824)
|
1/13/2006 7:18:53 PM
|
|
On Fri, 13 Jan 2006 19:18:53 GMT in comp.arch.embedded, Jonathan
Kirwan <jkirwan@easystreet.com> wrote:
>On Fri, 13 Jan 2006 10:47:45 -0600, Dave Hansen <iddw@hotmail.com>
>wrote:
>
>>"a[i]" has *exactly* the same meaning as "(*a + i)" whether a is a
>>pointer or array.
>
>You mean *((a)+(i)). Or perhaps more precisely, to capture usual
Actually, I meant "*(a + i)". Apologies for fat-fingering that. I
think, however, the additional parentheses in *((a)+(i)) are
redundant, at least if a[i] is a well-formed expression.
>unary conversion rules, *((&a[0])+(i)).
Well, no, actually, that's not necessary, and arguably wrong. Consider
i[a], which should be equivalent to a[i].
Regards,
-=Dave
--
Change is inevitable, progress is not.
|
|
0
|
|
|
|
Reply
|
iddw (679)
|
1/13/2006 7:35:51 PM
|
|
On 13 Jan 2006 14:27:32 GMT, "John B"
<spamj_baraclough@blockerzetnet.co.uk> wrote:
>On 12/01/2006 the venerable Chuck F. etched in runes:
>
>> Rufus V. Smith wrote:
>> >"#define" <u4karsh@gmail.com> wrote in message
>> > >
>> > > Some C questions were bugging me from quite some time. Any answers!
>> > > please share.
>> > >
>> > > 2. Given 2 Strings char *str1 = "JHONSON";
>> >> char *str2 = "O";
>> > >
>> > > what is the fastest way to remove all occurences of letter O
>> > > from str1.
>> >
>> > str1[0] = '\0';
>>
>> Bzzt - WRONG. str1 contains a pointer to a non-modifiable string (which may well reside in ROM).
>> str1 itself contains no letter O. Thus the only way is:
>>
>> str1 = "JHNSN";
>>
>> Things would be different if the original declaration was:
>>
>> char str1[] = "JHONSON";
>>
>> which would have initialized a character array to a C string.
>
>Bzzzzt - WRONG.
>
>A pointer to non-modifiable string would be declared as
>
> const char *str1 = "JHONSON";
>
>
>The two declarations:
>
> char str1* = "JHONSON";
>
>and
>
> char str2[] = "JHONSON";
>
>both allocate space for a modifiable string. The difference being that the first one also creates a
>pointer to that string.
To expand on this:
const char *str1 = "some string";
It produces something akin to:
char unnamed[] = "some string";
const char *str1= &unnamed[0];
where 'unnamed' isn't accessible by name, at the language level.
....
However, there is an interesting question this called to mind that I'm
not precisely clear on, though I can explain my own mental model about
it. This is the issue of the string initializer itself.
I believe the array contents of 'unnamed' need not be (but may be)
modifiable. In other words, the compiler may or may not use read-only
memory such as flash for the location of 'unnamed's array of chars.
I'm a little unclear on this point, though. So perhaps someone can
cite the chapter in the standard that clarifies this.
In other words, do these two statements set up different type
qualifiers for the literal?
char *str1= "Hi there.";
char const *str2= "Hi there.";
Would a c compiler be allowed to "fold" these two constant arrays so
that they occupy the exact same memory?
I'm unclear on that, though my own mental model says that a compiler
may fold these together, despite the fact that the pointers to the
then-identical array of characters do NOT have the same type
qualifiers. And, further, I think whether or not the compiler places
such unnamed strings in read-only memory or read-write is not
specified by the language and the compiler is allowed to make either
choice.
But I don't know.
Jon
|
|
0
|
|
|
|
Reply
|
jkirwan (824)
|
1/13/2006 8:23:02 PM
|
|
On Fri, 13 Jan 2006 13:35:51 -0600, Dave Hansen <iddw@hotmail.com>
wrote:
>On Fri, 13 Jan 2006 19:18:53 GMT in comp.arch.embedded, Jonathan
>Kirwan <jkirwan@easystreet.com> wrote:
>
>>On Fri, 13 Jan 2006 10:47:45 -0600, Dave Hansen <iddw@hotmail.com>
>>wrote:
>>
>>>"a[i]" has *exactly* the same meaning as "(*a + i)" whether a is a
>>>pointer or array.
>>
>>You mean *((a)+(i)). Or perhaps more precisely, to capture usual
>
>Actually, I meant "*(a + i)". Apologies for fat-fingering that. I
>think, however, the additional parentheses in *((a)+(i)) are
>redundant, at least if a[i] is a well-formed expression.
Understood.
>>unary conversion rules, *((&a[0])+(i)).
>
>Well, no, actually, that's not necessary, and arguably wrong. Consider
>i[a], which should be equivalent to a[i].
See Harbison and Steele, 5th edition, page 141. I think it states
what I wrote.
Jon
|
|
0
|
|
|
|
Reply
|
jkirwan (824)
|
1/13/2006 8:25:33 PM
|
|
On Fri, 13 Jan 2006 20:25:33 GMT in comp.arch.embedded, Jonathan
Kirwan <jkirwan@easystreet.com> wrote:
>On Fri, 13 Jan 2006 13:35:51 -0600, Dave Hansen <iddw@hotmail.com>
>wrote:
>
>>On Fri, 13 Jan 2006 19:18:53 GMT in comp.arch.embedded, Jonathan
>>Kirwan <jkirwan@easystreet.com> wrote:
>>
[...]
>
>>>unary conversion rules, *((&a[0])+(i)).
>>
>>Well, no, actually, that's not necessary, and arguably wrong. Consider
>>i[a], which should be equivalent to a[i].
>
>See Harbison and Steele, 5th edition, page 141. I think it states
>what I wrote.
Well, maybe I'm jut getting nitpicky. Which is why I qualified my
statement with "arguably."
My point was that it's not a positional thing, e.g., that i[a] is not
equivalent to *((&i[0])+(a)). As i stated in my earlier post, the
unadorned name of an array devolves into a pointer to the first
element of that array. In the reference, Harbison names the mechanism
by which this occurs (the ususal unary conversions).
Note that in the same paragraph he says what I said above, namely i[a]
is equivalent to a[i].
Regards,
-=Dave
--
Change is inevitable, progress is not.
|
|
0
|
|
|
|
Reply
|
iddw (679)
|
1/13/2006 8:44:28 PM
|
|
On Fri, 13 Jan 2006 14:44:28 -0600, Dave Hansen <iddw@hotmail.com>
wrote:
>Well, maybe I'm jut getting nitpicky. Which is why I qualified my
>statement with "arguably."
That's fine. Now, have you looked at my question regarding the
contents of unnamed string initializers? I've done a brief look at
the C99 standard and haven't found a specific answer (which may mean
it is buried in a chain of logic.) I also have looked through three
Harbinson and Steele editions without luck. I may jump into my
compiler books (like the two editions of the 'dragon' book, and
others) to see if I can find it referenced there. But I don't have a
good model for this in my head and looking at these examples exposed
my own ignorance on that specific point.
Jon
|
|
0
|
|
|
|
Reply
|
jkirwan (824)
|
1/13/2006 8:51:04 PM
|
|
On Fri, 13 Jan 2006 20:23:02 GMT, I wrote:
><snip>
>Would a c compiler be allowed to "fold" these two constant arrays so
>that they occupy the exact same memory?
><snip>
Actually, I think folding two strings together (which is an option on
some compilers) may be against the standard. So that part of the
question may not be relevant. But the subtler question remains as to
whether or not the string initializers themselves should be considered
unmodifiable by a programmer. I'd argue that they must be considered
unmodifiable, as some operating systems/compilers may place these
constants in "program text areas" or otherwise in read-only protected
memory. So that when saying:
char *s1= "hello";
you are doing something like,
char *s1= (char *) ((const char []) { "hello" });
Jon
|
|
0
|
|
|
|
Reply
|
jkirwan (824)
|
1/13/2006 9:08:22 PM
|
|
Ian Bell wrote:
> Ico wrote:
>
>>I don't see how I could be helpful at all in this case. I believe that
>>having a compiler that by default stores
>>
>>char msg[] = "Hello";
>>
>>into read only memory really *is* broken, and there is nothing I can do
>>about that by writing in a newsgroup, is there ?
>>
>
>
> You miss the point. Just because a compiler is not ANSI compliant does not
> mean it is broken. C was never designed to run on ROM based systems. The
> 'problems' only occur when people forget this.
>
In practice, there is little difference between a ROM based system and a
virtual memory implementation with read only pages. The same rules
apply, if your desktop compiler put the above string in a read only
segment, it would most certainly be called broken.
So there is little difference in design between ROM based and virtual
memory based compilers.
Ian C.
|
|
0
|
|
|
|
Reply
|
ian-news (9880)
|
1/13/2006 9:27:30 PM
|
|
>> > > Some C questions were bugging me from quite some time. Any answers!
>> > > please share.
well, your assignment's probably overdue, but as it's been bugging you...
>> > > 2. Given 2 Strings char *str1 = "JHONSON";
>> >> char *str2 = "O";
>> > > what is the fastest way to remove all occurences of letter O
>> > > from str1.
>> > str1[0] = '\0';
he didn't specify what to do with the remaining characters.
maybe str1 = "";
or str1 = "please finish my assignments";
it's not clear what role str2 plays in this question.
--
mac the na�f
|
|
0
|
|
|
|
Reply
|
alexc8 (94)
|
1/13/2006 9:28:23 PM
|
|
On 13/01/2006 the venerable Jonathan Kirwan etched in runes:
> On Fri, 13 Jan 2006 20:23:02 GMT, I wrote:
>
> > <snip>
> > Would a c compiler be allowed to "fold" these two constant arrays so
> > that they occupy the exact same memory?
> > <snip>
>
> Actually, I think folding two strings together (which is an option on
> some compilers) may be against the standard. So that part of the
> question may not be relevant. But the subtler question remains as to
> whether or not the string initializers themselves should be considered
> unmodifiable by a programmer. I'd argue that they must be considered
> unmodifiable, as some operating systems/compilers may place these
> constants in "program text areas" or otherwise in read-only protected
> memory. So that when saying:
>
> char *s1= "hello";
>
> you are doing something like,
>
> char *s1= (char *) ((const char []) { "hello" });
>
> Jon
We must also remember that C was devised for use on a machine with Von-Neuman architecture. Many
modern microcontrollers use a Harvard architecture and this presents the compiler writers with the
problem of where to put unmodifiable data.
--
John B
|
|
0
|
|
|
|
Reply
|
spamj_baraclough (152)
|
1/13/2006 9:38:47 PM
|
|
Jonathan Kirwan wrote:
>
.... snip ...
>
> char *str1= "Hi there."; char const *str2= "Hi there.";
>
> Would a c compiler be allowed to "fold" these two constant
> arrays so that they occupy the exact same memory?
In a word, yes.
--
"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
More details at: <http://cfaj.freeshell.org/google/>
|
|
0
|
|
|
|
Reply
|
cbfalconer (19183)
|
1/13/2006 11:15:05 PM
|
|
On 13 Jan 2006 21:38:47 GMT, "John B"
<spamj_baraclough@blockerzetnet.co.uk> wrote:
>On 13/01/2006 the venerable Jonathan Kirwan etched in runes:
>
>> On Fri, 13 Jan 2006 20:23:02 GMT, I wrote:
>>
>> > <snip>
>> > Would a c compiler be allowed to "fold" these two constant arrays so
>> > that they occupy the exact same memory?
>> > <snip>
>>
>> Actually, I think folding two strings together (which is an option on
>> some compilers) may be against the standard. So that part of the
>> question may not be relevant. But the subtler question remains as to
>> whether or not the string initializers themselves should be considered
>> unmodifiable by a programmer. I'd argue that they must be considered
>> unmodifiable, as some operating systems/compilers may place these
>> constants in "program text areas" or otherwise in read-only protected
>> memory. So that when saying:
>>
>> char *s1= "hello";
>>
>> you are doing something like,
>>
>> char *s1= (char *) ((const char []) { "hello" });
>>
>> Jon
>
>We must also remember that C was devised for use on a machine with
>Von-Neuman architecture.
The PDP-11, for one.
>Many modern microcontrollers use a Harvard architecture
I'm intimately aware of that.
>and this presents the compiler writers with the
>problem of where to put unmodifiable data.
Some thoughts on that:
The problem presented with any compiler used for dedicated embedded
situations is all the work it takes to meet the spec before arriving
at main(). At the time c was being developed, the current thinking
about running program environments included the following functional
classifications:
Segment Name Segment Description
-------------------------------------------------
CODE Code section
CONST Constant data section
INIT Initialized data section
BSS Uninitialized data section
HEAP Heap section
STACK Stack section
[Actually, the very concept of 'stack' as a general purpose workhorse
will still in its childhood -- many of the existing and commercially
successful machines did NOT support, via hardware, the idea of a stack
and a great deal of code had been written completely without them
except as a specialized concept for certain problems. (I worked on
such operating systems and languages.) Heap was kind of new, too. The
PDP-11 was only just out around 1970, or so, to light the way out of
the darkness. :) ]
In Von Neumann, all of these are in the same memory addressing system.
Modern concepts weren't completely worked out and the PDP-11 included
support for several equally good conventions. But the gist of the
above is that stack would grow down, heap grow up, and that the other
four sections were each of fixed size at start. Only the CODE, CONST
and INIT sections needed to be kept "on disk" or in some form of
non-volatile storage (which could, of course, include cards, tape, or
whatever.) Neatly, the non-volatile portions are all of fixed size.
In other words, like this:
Section Description Access NV? Size
=================================================================
Code Execute Yes Fixed/static
Constants Read Yes Fixed/static
Initialized Data Read/Write Yes Fixed/static
Uninitialized Data Read/Write No Fixed/static
Heap Read/Write No Variable, up
Stack Read/Write No Variable, down
If you look at the above list and think about Harvard architectures
and c programming generally, you find that the code must be placed in
code memory while the others must all be placed in data memory. on
Von Neumann, this is the same memory system. On Harvard, two
different ones, at least.
But this is NOT a problem, really. Even in the Harvard case. In
fact, it's not too far from how an operating system would do it under
the Intel 80386 and above, if it wanted to implement an execute-only
region for the code (you can't read it as data.) And the 80386 is NOT
Harvard.
Also, keep in mind that it is still the case that the first three must
be stored somewhere in non-volatile memory. In the case of Von
Neumann systems with flash on-chip, this is fairly easy -- just place
it there. Both code and data can be accessed without having to move
any of it around.
A question for c in embedded use for Harvard comes in the use of
pointers. A pointer to code memory may NOT occupy the same memory
footprint (in other words, the sizeof() the two pointer types may be
different) and the actual instructions used to access these different
types of memory may be different. The different size can be fixed, by
requiring the larger of the two sizes for all (in other words, making
a union.) And code generation can simply depend on the declaration of
the pointer. I believe casting can also be handled. So, frankly,
neither of these are insurmountable and it is quite possible for a c
compiler to accept straight c code and generate functioning programs
on Harvard machines without special decorations/declarations.
For Harvard, a re-definition of the Von Neumann layout is in order, if
you want to be able to port code as easily as to another Von Neumann
system. Something like these functional areas:
Segment Name Segment Description
-------------------------------------------------
CODE Code section
CONST_copy Data for constant section
INIT_copy Data for initialized data section
CONST Constant data section
INIT Initialized data section
BSS Uninitialized data section
HEAP Heap section
STACK Stack section
In this case, the first three must be placed in non-volatile memory --
flash, for example. And the remaining can be placed in volatile. At
start, pre-main() code copies CONST_copy into CONST and INIT_copy into
INIT before starting main(). If this is done, then once again all
data memory is accessible as data. And Harvard works consistently
with c's model, I think, in this case.
For embedded Harvard processors -- the only difficult problem in the
above is if there are _no_ instructions which can read from code space
and if the code space is the only non-volatile memory present. In
such cases, I believe, space will have to be reserved in data memory
and code instructions must be able to use immediate-mode constants
they can load into registers and then place into data memory to
initialize them to specific values. That would be painful, but
doable, if instructions support some form of immediate mode and there
is enough code space, of course.
So the bottom line, I think, is that Harvard really isn't exactly an
insurmountable problem for c compilers accepting unvarnished c code,
granting an instruction type or two on the target.
That is, until you worry about practical things like scarce resources
-- such as RAM. It is one thing that INIT_copy needs to be copied
into INIT. There is no avoiding the need to use RAM for initialized
data that can be later modified. It has to be in RAM. But CONST_copy
must also then be copied into RAM where it can be accessed as data and
it would be nice if, instead, those constants could just remain in the
code space and not take up RAM resources at run-time.
So that can be a bad thing. There may not be very much RAM to go
around. So suddenly you have a strong desire to access data that sits
in code space (if data space doesn't include non-volatile memory.) But
if you cave into that desire then you may have another problem,
passing around pointers to data which may be either in code space or
data space. In that case, you either need to fashion data pointers
which support both (and that will likely balloon the code as well as
slow execution time) or else have the compiler emit code for one kind
of access where that routine then cannot accept pointers to the other
space. I was faced with this problem, for example, using the PIC
chips -- in a routine that was basically a "printf()" accepting
strings which could _either_ be in a RAM buffer _or_ constant literals
located in code space.
So vendors do expand things by adding type qualifiers or #pragma
statements. But mostly to be competitive and sell their product --
not so much because they absolutely have to -- Harvard can be painful
for vanilla c and it can be uncompetitive with decorations added, but
I don't think it is impossible in principle.
Jon
|
|
0
|
|
|
|
Reply
|
jkirwan (824)
|
1/14/2006 2:56:55 AM
|
|
Paul Burke wrote:
>
> Ico wrote:
> >
> > I don't see how I could be helpful at all in this case. I believe that
> > having a compiler that by default stores
> >
> > char msg[] = "Hello";
> >
> > into read only memory really *is* broken, and there is nothing I can do
> > about that by writing in a newsgroup, is there ?
>
> The trouble is that the standard doesn't take the requirements of small
> embedded systems into account. Most compilers (for microcontrollers)
> will create the string as an initialised variable in RAM. To force it
> into another space, different compilers come up with different
> constructs. Some use 'const' as a marker that the string is to be in
> ROM. Others add extra keywords like 'code'. Others still put all
> initialised strings into ROM unless you tell them not to. And it's a
> bugger when porting code.
It depends on what you mean by initialized strings. I would call the
example an initialized char array. The char array must go into RAM.
Contrast the above code with
char *msg = "Hello"; (or better: const char *msg= "Hello";)
or
#define msg "Hello"
which may safely allocate the string literal in ROM.
--
Thad
|
|
0
|
|
|
|
Reply
|
ThadSmith (1279)
|
1/14/2006 4:34:22 PM
|
|
Dave Hansen <iddw@hotmail.com> wrote:
> My point was that it's not a positional thing, e.g., that i[a] is not
> equivalent to *((&i[0])+(a)). As i stated in my earlier post, the
> unadorned name of an array devolves into a pointer to the first
> element of that array.
That's still incorrect. The actual rule is that any expression of
array type (not just "the name of an array variable"!) used in a way
that requires a pointer, automagically turns into a pointer to its
first element. The canonical counter-example is that
sizeof(array) == sizeof(&(array[0]))
will be true only rather rarely.
--
Hans-Bernhard Broeker (broeker@physik.rwth-aachen.de)
Even if all the snow were burnt, ashes would remain.
|
|
0
|
|
|
|
Reply
|
broeker (1253)
|
1/16/2006 2:12:50 PM
|
|
Jonathan Kirwan <jkirwan@easystreet.com> wrote:
> Actually, I think folding two strings together (which is an option on
> some compilers) may be against the standard.
Incorrect. Constant folding was even among the rationales for making
string literals non-modifiable.
> So that part of the
> question may not be relevant. But the subtler question remains as to
> whether or not the string initializers themselves should be considered
> unmodifiable by a programmer.
They *must* be considered immutable. Any program assuming differently
will cause undefined behaviour. Which means that such a program would
be about as fundamentally buggy as a program can possibly be and still
make it through some compilers.
As I've written here before, the fact that the type of "hello" is
formally "array of char" instead of "array of const char" is a
historical accident.
--
Hans-Bernhard Broeker (broeker@physik.rwth-aachen.de)
Even if all the snow were burnt, ashes would remain.
|
|
0
|
|
|
|
Reply
|
broeker (1253)
|
1/16/2006 2:21:35 PM
|
|
John B <spamj_baraclough@blockerzetnet.co.uk> wrote:
> We must also remember that C was devised for use on a machine with
> Von-Neuman architecture. Many modern microcontrollers use a Harvard
> architecture and this presents the compiler writers with the problem
> of where to put unmodifiable data.
Harvard vs. von-Neumann architecture has little or nothing to do with
that. The only question is whether the target platform has some kind
of read-only memory accessible as data (rather than only as code) or
not. If data ROM is available, string literals should usually go
there. If there isn't, it doesn't matter where you put them.
--
Hans-Bernhard Broeker (broeker@physik.rwth-aachen.de)
Even if all the snow were burnt, ashes would remain.
|
|
0
|
|
|
|
Reply
|
broeker (1253)
|
1/16/2006 2:29:42 PM
|
|
On 16 Jan 2006 14:21:35 GMT, Hans-Bernhard Broeker
<broeker@physik.rwth-aachen.de> wrote:
>Jonathan Kirwan <jkirwan@easystreet.com> wrote:
>
>> Actually, I think folding two strings together (which is an option on
>> some compilers) may be against the standard.
>
>Incorrect. Constant folding was even among the rationales for making
>string literals non-modifiable.
Constant folding would argue exactly that, of course. But the
rationale is not the standard. I would be interested in the section
of the standard where this is addressed. Anyway, I was guessing in
the back of my mind about the potential distinctness of pointers to
two different instances of the same literal text and whether or not it
might be allowed to have the same address. I haven't thought deeply
about it and I don't recall reading a specific point in the standard,
so that was my guess. Now, I suppose, I should have to go more deeply
into it. Unless you have a ready citation.
And thanks for the point.
>> So that part of the
>> question may not be relevant. But the subtler question remains as to
>> whether or not the string initializers themselves should be considered
>> unmodifiable by a programmer.
>
>They *must* be considered immutable. Any program assuming differently
>will cause undefined behaviour. Which means that such a program would
>be about as fundamentally buggy as a program can possibly be and still
>make it through some compilers.
Makes a lot of sense to me.
>As I've written here before, the fact that the type of "hello" is
>formally "array of char" instead of "array of const char" is a
>historical accident.
I didn't read what you wrote before. Thanks.
Jon
|
|
0
|
|
|
|
Reply
|
jkirwan (824)
|
1/16/2006 6:31:11 PM
|
|
Jonathan Kirwan <jkirwan@easystreet.com> wrote:
> I would be interested in the section of the standard where this is
> addressed.
Well, I don't have a copy of C89, but see K&R2 (ANSI C edition),
appendix section A.2.6. Also see the C FAQ, entry 1.32, and
references therein.
> Anyway, I was guessing in the back of my mind about the
> potential distinctness of pointers to two different instances of the
> same literal text and whether or not it might be allowed to have the
> same address.
They're explicitly neither forbidden, nor guaranteed, to be the same.
This falls under the general heading of implementation-defined
behaviour.
Some people may think that the need for a distinction between two
objects being the same vs. them being equal is a novelty of OO
programming. Well, it's not.
--
Hans-Bernhard Broeker (broeker@physik.rwth-aachen.de)
Even if all the snow were burnt, ashes would remain.
|
|
0
|
|
|
|
Reply
|
broeker (1253)
|
1/16/2006 6:51:46 PM
|
|
On 16 Jan 2006 18:51:46 GMT, Hans-Bernhard Broeker
<broeker@physik.rwth-aachen.de> wrote:
>Jonathan Kirwan <jkirwan@easystreet.com> wrote:
>
>> I would be interested in the section of the standard where this is
>> addressed.
>
>Well, I don't have a copy of C89, but see K&R2 (ANSI C edition),
>appendix section A.2.6. Also see the C FAQ, entry 1.32, and
>references therein.
I'd like to see it in the standard, but I looked at your reference in
K&R 2nd ed. And it says what you say it says.
>> Anyway, I was guessing in the back of my mind about the
>> potential distinctness of pointers to two different instances of the
>> same literal text and whether or not it might be allowed to have the
>> same address.
>
>They're explicitly neither forbidden, nor guaranteed, to be the same.
>This falls under the general heading of implementation-defined
>behaviour.
That's what K&R 2nd ed. appears to say. I'm with you, there.
>Some people may think that the need for a distinction between two
>objects being the same vs. them being equal is a novelty of OO
>programming. Well, it's not.
I wasn't thinking of OO here. However, I'll see if I can find the
point referenced in C99 or C89. I like the points you've made, but
I'm still curious.
Jon
|
|
0
|
|
|
|
Reply
|
jkirwan (824)
|
1/16/2006 7:34:03 PM
|
|
|
44 Replies
43 Views
(page loaded in 0.473 seconds)
Similiar Articles: Embedded MATLAB Editor Function - processing data #2 - comp.soft ...I am stuck while making program in Embedded Matlab Function Block and i need your help. ... Post Question | Groups | ... Small Linux SBC in the $50 price range? - comp.arch.embedded ...OOPIC Compiler Question - comp.arch.embedded Small Linux SBC in the $50 price range? - comp.arch.embedded ... OOPIC Compiler Question - comp.arch.embedded Small Linux SBC ... comp.arch.embedded - page 2interfacing cpld 9 72 (11/21/2009 10:06:51 PM) Hi there, a newbie question, and I would be grateful for a response or at least hint where to look(read) for information. Cross-Compile for ARM - NTP 4.1.1 OK, NTP 4.2.0a Errors - comp ...... targeted at an Arcom ARM-based embedded board, with the Acrom Embedded Linux (AEL) 3.7 (kernel 2.... ... Post Question | Groups ... Solution Manual and Test Bank - comp.arch.embedded... Post Question | Groups ... Resolution A Conflict Diagnosis Approach Coltri 2 ... Solution Manual and Test Bank - comp.arch.embedded Hi dear ... test for embedded fonts programmatically - comp.text.pdf ...I would like to figure out if all the fonts in the pdf are embedded. He... ... Post Question | Groups | ... Embedded matlab function in simulink for mutiple inputs and ...I have one more question, how to define the size of the variable. For example: If ... Embedded matlab function in simulink for mutiple inputs and ... I'm using embedded ... embedded WMP, button to play in full screen - comp.lang.javascript ...i want to make a button that will start an embedded windows media player playing AND ... You'll have to decide, based on the answers to those questions, whether the play ... Arm Development Suite version 1.2 - comp.arch.embeddedArm Development Suite version 1.2 - comp.arch.embedded TradeStation 8.8 with Owndata 2.8 ... Questions to Solstice OSI 9.0 for Solaris 10 - comp.unix.solaris ... Installing ... Time going backwards - comp.protocols.time.ntpHi Folks, I have some questions about when (if ever) NTP will set time backward. I'll be using it on Embedded Linux for time stamping video frames. ... ntpd on embedded risc - comp.protocols.time.ntpI was so concentrated on the rate question I negected the fact ... interval, and loopstats - comp.protocols.time ... ntpd on embedded risc - comp.protocols.time.ntp ntpd 4.2 ... FOP embed user defined chinese character ?? - comp.text.pdf ...... Everyone, By using the "userconfig.xml", standard chinese characters can be embedded ... page-sequence, fo:block or fo:character): ... not found there, please post a question ... Need *very* small NTP-Server for Linux - comp.protocols.time.ntp ...... bug in sntp that will be fixed for the ntp-4.2.1 ... want to publish the time of the clock on the "embedded ... questions mailing list questions@lists.ntp.isc.org https ... Altera logic programmer card - comp.arch.fpgaWhich embedded O/S for a 32-bit RISC microcontroller? 6 52 Cla ... VHDL FF Question 2 52 Brendan Merging pdf files - embedded font - comp.text.pdf... Post Question | Groups | ... It's not very easy to check if 2 embedded fonts are the same font and remove one of ... Embedded Questions - Learn American English OnlineThis page provides an explanation for forming embedded questions in English. Embedded Questions - Lesson 28, Part 2 - English Grammar - YouTubeTopic: Embedded questions. In Part 2, we look beyond the use of embedded questions as subjects and direct objects. We study embedded questions as indirect ... 7/25/2012 1:37:01 AM
|