Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.c > #6574 > unrolled thread

int * vs char *

Started byyugandhar <nospam@nospam.com>
First post2011-06-21 21:49 +0000
Last post2011-06-21 21:29 -0500
Articles 20 on this page of 53 — 20 participants

Back to article view | Back to comp.lang.c


Contents

  int * vs char * yugandhar <nospam@nospam.com> - 2011-06-21 21:49 +0000
    Re: int * vs char * John Gordon <gordon@panix.com> - 2011-06-21 21:58 +0000
      Re: int * vs char * "Morris Keesan" <mkeesan@post.harvard.edu> - 2011-06-21 20:25 -0400
    Re: int * vs char * Ian Collins <ian-news@hotmail.com> - 2011-06-22 09:59 +1200
    Re: int * vs char * Ike Naar <ike@sverige.freeshell.org> - 2011-06-21 22:18 +0000
    Re: int * vs char * Shao Miller <sha0.miller@gmail.com> - 2011-06-21 18:34 -0500
    Re: int * vs char * Keith Thompson <kst-u@mib.org> - 2011-06-21 15:42 -0700
      Re: int * vs char * Noob <root@127.0.0.1> - 2011-06-22 10:28 +0200
        Re: int * vs char * Shao Miller <sha0.miller@gmail.com> - 2011-06-22 05:23 -0500
        Re: int * vs char * James Kuyper <jameskuyper@verizon.net> - 2011-06-22 06:25 -0400
          Re: int * vs char * Ian Collins <ian-news@hotmail.com> - 2011-06-23 07:56 +1200
            Re: int * vs char * Shao Miller <sha0.miller@gmail.com> - 2011-06-22 18:12 -0500
              Re: int * vs char * Ian Collins <ian-news@hotmail.com> - 2011-06-23 10:23 +1200
              Re: int * vs char * Keith Thompson <kst-u@mib.org> - 2011-06-22 17:23 -0700
                Re: int * vs char * Ian Collins <ian-news@hotmail.com> - 2011-06-23 12:54 +1200
                  Re: int * vs char * Keith Thompson <kst-u@mib.org> - 2011-06-22 18:18 -0700
                    Re: int * vs char * Ian Collins <ian-news@hotmail.com> - 2011-06-23 13:23 +1200
                Re: int * vs char * Shao Miller <sha0.miller@gmail.com> - 2011-06-24 15:39 -0400
                  Re: int * vs char * Ian Collins <ian-news@hotmail.com> - 2011-06-25 09:28 +1200
                    Re: int * vs char * Keith Thompson <kst-u@mib.org> - 2011-06-24 14:58 -0700
                      Re: int * vs char * Ian Collins <ian-news@hotmail.com> - 2011-06-25 10:06 +1200
                    Re: int * vs char * Shao Miller <sha0.miller@gmail.com> - 2011-06-26 15:44 -0500
                  Re: int * vs char * Keith Thompson <kst-u@mib.org> - 2011-06-24 14:29 -0700
                    Re: int * vs char * Ian Collins <ian-news@hotmail.com> - 2011-06-25 09:36 +1200
                    Re: int * vs char * Shao Miller <sha0.miller@gmail.com> - 2011-06-26 16:24 -0500
                  Re: int * vs char * Tim Rentsch <txr@alumni.caltech.edu> - 2011-06-25 08:39 -0700
              Re: int * vs char * gordonb.5qick@burditt.org (Gordon Burditt) - 2011-06-22 23:49 -0500
        Re: int * vs char * Stephen Sprunk <stephen@sprunk.org> - 2011-06-22 11:31 -0500
          Re: int * vs char * gordonb.idn9q@burditt.org (Gordon Burditt) - 2011-06-23 00:45 -0500
            Re: int * vs char * pacman@kosh.dhis.org (Alan Curry) - 2011-06-23 20:08 +0000
            Re: int * vs char * Stephen Sprunk <stephen@sprunk.org> - 2011-06-23 22:40 -0500
              Re: int * vs char * Ian Collins <ian-news@hotmail.com> - 2011-06-24 15:46 +1200
                Re: int * vs char * Stephen Sprunk <stephen@sprunk.org> - 2011-06-24 09:24 -0500
                  Re: int * vs char * Shao Miller <sha0.miller@gmail.com> - 2011-07-04 18:00 -0400
                    Re: int * vs char * Dr Nick <3-nospam@temporary-address.org.uk> - 2011-07-05 07:45 +0100
                      Re: int * vs char * Harald van Dijk <truedfx@gmail.com> - 2011-07-05 10:39 -0700
                        Re: int * vs char * Shao Miller <sha0.miller@gmail.com> - 2011-07-05 14:09 -0400
                          Re: int * vs char * Phil Carmody <thefatphil_demunged@yahoo.co.uk> - 2011-07-07 21:56 +0300
                            Re: int * vs char * Phil Carmody <thefatphil_demunged@yahoo.co.uk> - 2011-07-08 02:46 +0300
                              Re: int * vs char * Shao Miller <sha0.miller@gmail.com> - 2011-07-07 22:26 -0400
                                Re: int * vs char * Stephen Sprunk <stephen@sprunk.org> - 2011-07-07 22:41 -0500
                    Re: int * vs char * "Joel C. Salomon" <joelcsalomon@gmail.com> - 2011-07-05 15:32 -0400
                      Re: int * vs char * Shao Miller <sha0.miller@gmail.com> - 2011-07-06 09:58 -0400
        Re: int * vs char * Tim Rentsch <txr@alumni.caltech.edu> - 2011-06-23 01:02 -0700
          Re: int * vs char * Ian Collins <ian-news@hotmail.com> - 2011-06-23 20:11 +1200
            Re: int * vs char * Tim Rentsch <txr@alumni.caltech.edu> - 2011-06-25 09:23 -0700
              Re: int * vs char * Keith Thompson <kst-u@mib.org> - 2011-06-25 12:37 -0700
                Re: int * vs char * Tim Rentsch <txr@alumni.caltech.edu> - 2011-06-27 11:40 -0700
    Re: int * vs char * Eric Sosman <esosman@ieee-dot-org.invalid> - 2011-06-21 21:46 -0400
      Re: int * vs char * "Kleuskes & Moos" <kleuske@xs4all.nl> - 2011-06-22 10:06 -0700
        Re: int * vs char * Keith Thompson <kst-u@mib.org> - 2011-06-22 13:06 -0700
          Re: int * vs char * "Kleuskes & Moos" <kleuske@xs4all.nl> - 2011-06-22 13:29 -0700
    Re: int * vs char * Stephen Sprunk <stephen@sprunk.org> - 2011-06-21 21:29 -0500

Page 2 of 3 — ← Prev page 1 [2] 3  Next page →


#6900

FromIan Collins <ian-news@hotmail.com>
Date2011-06-25 10:06 +1200
Message-ID<96kg41Fb9tU10@mid.individual.net>
In reply to#6898
On 06/25/11 09:58 AM, Keith Thompson wrote:
> Ian Collins<ian-news@hotmail.com>  writes:
>> On 06/25/11 07:39 AM, Shao Miller wrote:
> [...]
>>> Well doesn't 'const' "come from" C++, anyway?
>>
>> No, it's just used properly there!
>
> See the ANSI C Rationale, at
> <http://www.lysator.liu.se/c/rat/c5.html#3-5-3>:
>
>      The Committee has added to C two type qualifiers: const and
>      volatile.  Individually and in combination they specify the
>      assumptions a compiler can and must make when accessing an
>      object through an lvalue.
>
>      The syntax and semantics of const were adapted from C++; the
>      concept itself has appeared in other languages.  volatile is
>      an invention of the Committee; it follows the syntactic model
>      of const.

OK, but it was standardised in C long before C++.

-- 
Ian Collins

[toc] | [prev] | [next] | [standalone]


#6982

FromShao Miller <sha0.miller@gmail.com>
Date2011-06-26 15:44 -0500
Message-ID<iu8276$bvo$1@dont-email.me>
In reply to#6887
On 6/24/2011 4:28 PM, Ian Collins wrote:
> On 06/25/11 07:39 AM, Shao Miller wrote:
>> On 6/22/2011 20:23, Keith Thompson wrote:
>>
>>> The fact that I've never heard of anyone implementing something like
>>> this suggests (though not strongly) that there's no demand for it.
>>>
>>
>> Suppose you've a program loaded into memory via a serial line. Suppose
>> the program is loaded into writable memory (that seems pretty likely).
>> Suppose the program offers a CLI. Suppose a user can rename commands or
>> variables, or redefine preset scripts.
>
> A recipe for disaster! What happens if a new name is linger than the old?
>

When it's time to overwrite, count how many characters before the null 
character and limit accordingly.  This'd mean that redefining these 
could narrow the strings and one couldn't redefine with a larger string 
afterwards, but a script mightn't need to redefine more than once; i.e. 
defaults.

But I wouldn't worry about that as much as I'd worry about the potential 
for shared storage. ;)

>> Yes, all of these could be done
>> cleanly (in my opinion) via 'static' 'char[]'s, but it can be more
>> convenient for some people to simply type the string literal right into
>> some spot in the source code where it's used and forget about coming up
>> with a meaningful (and possibly redundant) identifier, i.e.
>> 'csz_Hello__world___And_how_are_you__today_'
>
> Yuck, what a contrived example! As you say, there is a method that does
> not use undefined behaviour.
>

Yes, it is contrived.  Yes, it's cleaner the other way.  But ought our 
opinions to be enforced globally via such a change in the Standard? 
Some programmers might just like it.  Since I'm not one of them, maybe I 
shouldn't be attempting to defend their position.  Heh.

>>> I suspect that the vast majority of code that attempts to modify
>>> string literals does so as the result of bugs.
>>
>> That seems probable to me, too.
>>
>>> A lot more code
>>> uses string literals in contexts that don't treat them as const,
>>> but doesn't actually try to modify them; for example:
>>>
>>> void func(char *s) {
>>>   printf("In func(), s = \"%s\"\n");
>>> }
>>>
>>> ...
>>>
>>> func("hello");
>>>
>>> In short, I think the issue is not that anyone wants to modify
>>> string literals;
>>
>> For the right use case, I would.
>>
>>> it's that making them const would break existing
>>> code that *doesn't* actually modify string literals.
>>>
>>> (Stroustrup was able to do this in C++ because there was no existing
>>> C++ code before he invented the language.)
>>>
>>
>> Well doesn't 'const' "come from" C++, anyway?
>
> No, it's just used properly there!
>

I really thought it did come from C++.  Oops.

>> And why isn't there a write-only counterpart, for symmetry, such as a
>> memory-mapped port that mustn't be read from?
>
> That case isn't uncommon in embedded systems (watchdog reset being a
> common example). However reading is generally harmless.
>

But a "write-only" attribute still adds useful information.  A 
programmer coming along to work on someone else's code mightn't realize 
that there is no expectation whatsoever for the value of an object, once 
read.  Such an attribute could allow them to find that out at 
translation time.  It's a digression, anyway. :)

>> And during very early development (and Usenet code examples), can it be
>> pleasant to avoid 'const' concerns altogether and then to analyze and
>> refine, gradually sprinkling 'const' in where appropriate? I don't
>> advocate this, but imagine that some folks might get "stuck" in
>> "analysis paralysis" if they had to think 'const'ness through at every
>> corner. I could be mistaken.
>
> Not really, if you don't know whether the function you are writing will
> modify its arguments, you are big trouble!
>

That seems just a bit beginner-unfriendly, to me.  I've seen beginners 
struggle with 'const'-ness quite a bit, especially with one or more 
levels of indirection.

My point just there is that the behaviour of a program can be the same 
with 'const' completely removed.  So it seems more like something that 
"ought to" be used rather than "must" be used.  But hey, that's just an 
opinion.

[toc] | [prev] | [next] | [standalone]


#6888

FromKeith Thompson <kst-u@mib.org>
Date2011-06-24 14:29 -0700
Message-ID<lnvcvudilc.fsf@nuthaus.mib.org>
In reply to#6865
Shao Miller <sha0.miller@gmail.com> writes:
> On 6/22/2011 20:23, Keith Thompson wrote:
>> Shao Miller<sha0.miller@gmail.com>  writes:
>>> On 6/22/2011 2:56 PM, Ian Collins wrote:
>>>> On 06/22/11 10:25 PM, James Kuyper wrote:
>> [...]
>>>> The existing code problem was a acknowledged when C++ changed the type
>>>> of string literals. Compilers may choose not to issues a diagnostic for
>>>> this case. Now we have had over a decade to fix the smelly code, I
>>>> believe a diagnostic is now required by the new C++ standard.
>>>>
>>>> C could and should have done the same, but as usual those worried about
>>>> breaking already broken code appear to have won the day.
>>>>
>>>
>>> Again, why should a C implementation be rendered non-conforming [to some
>>> future Standard] thusly?
>>>
>>> In a "bare metal" environment, one might very well wish to overwrite
>>> their string literals' storage, no?  The "bare metal" implementation
>>> might need to define such action as being appropriate.
>>>
>>> By using "proper" static arrays, we lose out on the "shared storage"
>>> benefit.  Writing for bare metal, hopefully one knows what one is doing.
>>>
>>> Is this example silly?
>>
>> If there's a need for a "bare metal" environment to be able to modify
>> string literals, that can be provided as an extension.
>
> As in, a documented extension?

Well, yes, documenting it would certainly be a nice touch.

>> Any code that
>> currently takes advantage of that ability already has undefined
>> behavior.
>>
>
> Exactly the nature of my question.  If there is at least one real 
> program that depends on this "undefined behaviour" (use the Standard 
> definition, please :) ),

If you were correcting my spelling from "behavior" to "behaviour", the
Standard uses the US-style "behavior" spelling.  If not, what do you
mean?

(Hmm, does the UK standard body, its equivalent of the US ANSI,
"translate" ISO standards into UK spellings?)

>                          then that program's source code might have to 
> be adjusted for future versions of an implementation, depending on how 
> that future implementation implements the extension.
>
>> If such a feature were desirable, we could have an optional 'M' (for
>> modifiable) prefix for string literals, similar to the existing 'L'
>> prefix for wide string literals.  For example, "hello" could be of type
>> const char[6], and M"hello" could be of type char[6]].
>>
>
> An interesting idea!  'M()' could get close, perhaps.
>
>    #define M(string) ((char[]){string})
>
> I guess we'd need 'ML', too?
>
>> The fact that I've never heard of anyone implementing something like
>> this suggests (though not strongly) that there's no demand for it.
>
> Suppose you've a program loaded into memory via a serial line.  Suppose 
> the program is loaded into writable memory (that seems pretty likely). 
> Suppose the program offers a CLI.  Suppose a user can rename commands or 
> variables, or redefine preset scripts.  Yes, all of these could be done 
> cleanly (in my opinion) via 'static' 'char[]'s, but it can be more 
> convenient for some people to simply type the string literal right into 
> some spot in the source code where it's used and forget about coming up 
> with a meaningful (and possibly redundant) identifier, i.e. 
> 'csz_Hello__world___And_how_are_you__today_'

And suppose the user wants to replace the content with a string that's
longer than the original literal.

[snip]

>> In short, I think the issue is not that anyone wants to modify
>> string literals;
>
> For the right use case, I would.

Perhaps.

There are benefits and drawbacks both to allowing modifications of
string literals, and to disallowing them.  IMHO the benefits of
disallowing modifications (catching potential errors) far outweight the
benefit for a few obscure use cases.

My M"..." proposal *could* give us the best of both, and I wouldn't
object if it showed up in a future standard.  I just don't think
it's sufficiently useful.

>> it's that making them const would break existing
>> code that *doesn't* actually modify string literals.
>>
>> (Stroustrup was able to do this in C++ because there was no existing
>> C++ code before he invented the language.)
>
> Well doesn't 'const' "come from" C++, anyway?

I think so.

> And why isn't there a write-only counterpart, for symmetry, such as a 
> memory-mapped port that mustn't be read from?

Lack of usefulness, I suppose.  "const" (which perhaps should have been
called "readonly") is massively useful.  "writeonly" would be probably
useful only in some very low-level code.  And an implementation could
provide a #pragma that does the same thing (have any done so?).

> And during very early development (and Usenet code examples), can it be 
> pleasant to avoid 'const' concerns altogether and then to analyze and 
> refine, gradually sprinkling 'const' in where appropriate?  I don't 
> advocate this, but imagine that some folks might get "stuck" in 
> "analysis paralysis" if they had to think 'const'ness through at every 
> corner.  I could be mistaken.

I think designing const into your code from the start is a lot
easier.

My personal preference is to declare everything "const" *unless*
I specifically need to modify it.  In fact, if I were designing
a new language (without concern for backward compatibility),
declared objects would be read-only by default, with some special
syntax ("var"?) to make them writable.  With sufficiently flexible
initialization, I suspect most objects don't need to be modified
after their creation.  (I do not for one moment suggesting making
such a change to C.)

-- 
Keith Thompson (The_Other_Keith) kst-u@mib.org  <http://www.ghoti.net/~kst>
Nokia
"We must do something.  This is something.  Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"

[toc] | [prev] | [next] | [standalone]


#6891

FromIan Collins <ian-news@hotmail.com>
Date2011-06-25 09:36 +1200
Message-ID<96keceFb9tU9@mid.individual.net>
In reply to#6888
On 06/25/11 09:29 AM, Keith Thompson wrote:
>
> If you were correcting my spelling from "behavior" to "behaviour", the
> Standard uses the US-style "behavior" spelling.  If not, what do you
> mean?
>
> (Hmm, does the UK standard body, its equivalent of the US ANSI,
> "translate" ISO standards into UK spellings?)

Alas, no.  We have to suffer the cultural imperialism!

-- 
Ian Collins

[toc] | [prev] | [next] | [standalone]


#6986

FromShao Miller <sha0.miller@gmail.com>
Date2011-06-26 16:24 -0500
Message-ID<iu84ia$s6q$1@dont-email.me>
In reply to#6888
On 6/24/2011 4:29 PM, Keith Thompson wrote:
> Shao Miller<sha0.miller@gmail.com>  writes:
>> On 6/22/2011 20:23, Keith Thompson wrote:
>>> Shao Miller<sha0.miller@gmail.com>   writes:
>>>> On 6/22/2011 2:56 PM, Ian Collins wrote:
>>>>> On 06/22/11 10:25 PM, James Kuyper wrote:
>>> [...]
>>>>> The existing code problem was a acknowledged when C++ changed the type
>>>>> of string literals. Compilers may choose not to issues a diagnostic for
>>>>> this case. Now we have had over a decade to fix the smelly code, I
>>>>> believe a diagnostic is now required by the new C++ standard.
>>>>>
>>>>> C could and should have done the same, but as usual those worried about
>>>>> breaking already broken code appear to have won the day.
>>>>>
>>>>
>>>> Again, why should a C implementation be rendered non-conforming [to some
>>>> future Standard] thusly?
>>>>
>>>> In a "bare metal" environment, one might very well wish to overwrite
>>>> their string literals' storage, no?  The "bare metal" implementation
>>>> might need to define such action as being appropriate.
>>>>
>>>> By using "proper" static arrays, we lose out on the "shared storage"
>>>> benefit.  Writing for bare metal, hopefully one knows what one is doing.
>>>>
>>>> Is this example silly?
>>>
>>> If there's a need for a "bare metal" environment to be able to modify
>>> string literals, that can be provided as an extension.
>>
>> As in, a documented extension?
>
> Well, yes, documenting it would certainly be a nice touch.
>
>>> Any code that
>>> currently takes advantage of that ability already has undefined
>>> behavior.
>>>
>>
>> Exactly the nature of my question.  If there is at least one real
>> program that depends on this "undefined behaviour" (use the Standard
>> definition, please :) ),
>
> If you were correcting my spelling from "behavior" to "behaviour", the
> Standard uses the US-style "behavior" spelling.  If not, what do you
> mean?
>

Oops; no.  Just an attempt to direct the interpretation of "that depends 
on this \"undefined behaviour\"".  It's previously been demonstrated 
that it might be interpreted as plain English rather than the precise 
Standard definition.

> (Hmm, does the UK standard body, its equivalent of the US ANSI,
> "translate" ISO standards into UK spellings?)
>

Heh.  I've no idea.

>>
>> Suppose you've a program loaded into memory via a serial line.  Suppose
>> the program is loaded into writable memory (that seems pretty likely).
>> Suppose the program offers a CLI.  Suppose a user can rename commands or
>> variables, or redefine preset scripts.  Yes, all of these could be done
>> cleanly (in my opinion) via 'static' 'char[]'s, but it can be more
>> convenient for some people to simply type the string literal right into
>> some spot in the source code where it's used and forget about coming up
>> with a meaningful (and possibly redundant) identifier, i.e.
>> 'csz_Hello__world___And_how_are_you__today_'
>
> And suppose the user wants to replace the content with a string that's
> longer than the original literal.
>

So let them.  That's a discussion about user expectations.  The user 
might even be the programmer, wishing to override some defaults for a 
particular client's needs.

Above is just an example for why a programmer might not want string 
literals to be 'const'-qualified, especially in an environment where 
'const' mightn't have any physical meaning; where all program memory is 
writable, and usefully so.

> [snip]
>
>>> In short, I think the issue is not that anyone wants to modify
>>> string literals;
>>
>> For the right use case, I would.
>
> Perhaps.
>
> There are benefits and drawbacks both to allowing modifications of
> string literals, and to disallowing them.  IMHO the benefits of
> disallowing modifications (catching potential errors) far outweight the
> benefit for a few obscure use cases.
>

They probably do out-weigh in terms of use cases, in my opinion.

> My M"..." proposal *could* give us the best of both, and I wouldn't
> object if it showed up in a future standard.  I just don't think
> it's sufficiently useful.
>

Agreed.

>>> it's that making them const would break existing
>>> code that *doesn't* actually modify string literals.
>>>
>>> (Stroustrup was able to do this in C++ because there was no existing
>>> C++ code before he invented the language.)
>>
>> Well doesn't 'const' "come from" C++, anyway?
>
> I think so.
>
>> And why isn't there a write-only counterpart, for symmetry, such as a
>> memory-mapped port that mustn't be read from?
>
> Lack of usefulness, I suppose.  "const" (which perhaps should have been
> called "readonly") is massively useful.

I find it useful as a quality measure, potential optimization 
opportunity, and for interface specification, but would find 
"write-only" useful for the same reasons.

> "writeonly" would be probably
> useful only in some very low-level code.  And an implementation could
> provide a #pragma that does the same thing (have any done so?).
>

Well MS has '_in', '_out', and '_inout'[1].

>> And during very early development (and Usenet code examples), can it be
>> pleasant to avoid 'const' concerns altogether and then to analyze and
>> refine, gradually sprinkling 'const' in where appropriate?  I don't
>> advocate this, but imagine that some folks might get "stuck" in
>> "analysis paralysis" if they had to think 'const'ness through at every
>> corner.  I could be mistaken.
>
> I think designing const into your code from the start is a lot
> easier.
>

That strikes me as a useful habit for:
- A programmer that understands 'const'
- A programmer that perceives benefits from using 'const'

I'm just not sure that's the set of all programmers.

> My personal preference is to declare everything "const" *unless*
> I specifically need to modify it.  In fact, if I were designing
> a new language (without concern for backward compatibility),
> declared objects would be read-only by default, with some special
> syntax ("var"?) to make them writable.  With sufficiently flexible
> initialization, I suspect most objects don't need to be modified
> after their creation.  (I do not for one moment suggesting making
> such a change to C.)
>

What are the major benefits of having such a read-only attribute as a 
default?  I think that there are lots of concepts translating to code 
constructs and patterns that make for high-quality code (such as 
'const'), but do they have meaning in every environment?  As an example, 
if "storage" can be "readable" and "writable," isn't it kind of pleasant 
that subsets can be defined by explicit inclusion of a predicate such as 
'const'?  As another example, if "storage" can be "addressable" and 
"non-addressable," isn't it kind of pleasant that subsets can be defined 
by explicit inclusion of a predicate such as 'register'?

But maybe you're right and maybe 'const'-default string literals could 
raise the average quality of C code. :)

[1] http://msdn.microsoft.com/en-us/library/aa383701%28v=VS.85%29.aspx

[toc] | [prev] | [next] | [standalone]


#6928

FromTim Rentsch <txr@alumni.caltech.edu>
Date2011-06-25 08:39 -0700
Message-ID<kfn1uyhc44i.fsf@x-alumni2.alumni.caltech.edu>
In reply to#6865
Shao Miller <sha0.miller@gmail.com> writes:

> [discussing modifiable string literals]
> 
> An interesting idea!  'M()' could get close, perhaps.
>
>   #define M(string) ((char[]){string})

Different storage duration.

[toc] | [prev] | [next] | [standalone]


#6695

Fromgordonb.5qick@burditt.org (Gordon Burditt)
Date2011-06-22 23:49 -0500
Message-ID<CaKdnTVwEJZGWJ_TnZ2dnUVZ_vydnZ2d@posted.internetamerica>
In reply to#6673
> In a "bare metal" environment, one might very well wish to overwrite 
> their string literals' storage, no?  

Usually just the opposite.

If I wish to "force" writability of specific string literals, I can
instead put them in character arrays.  Those have to go in writable
memory.  A compiler that uses writeable strings also isn't supposed
to consolidate those strings.  (For example:  "birthday" + 5 ==
"day" (no, I do not mean to call strcmp() here:  I am comparing
pointers, not strings) with non-writable strings might evaluate as
true because the compiler shares memory between the two, but it
shouldn't be doing that with writable strings.  (GCC offers a choice
here, and it seems to get this right both ways.  No consolidation
with writable strings.) Generally, on "bare metal" I'd want maximum
consolidation of string literals possible, and put them in ROM/code
flash, if possible.  You don't get much in the way of strings
in a processor with 128 or 256 bytes of RAM, total, including
the stack (yes, most of these processors have one, even if C does
not require it).

> The "bare metal" implementation 
> might need to define such action as being appropriate.

"bare metal" has a lot more problems of wishing to specify where
something is placed.  Also, RAM tends to be much more expensive
than ROM or flash, and "initialized data" usually takes up space
in both.  Starting the program involves copying from flash to
"initialized data" to RAM, and zeroing the "uninitialized data" in
RAM.  The OS might do this on a PC but on bare metal it can be done
by compiler start-up routines or done explicitly by the program
(GCC and binutils for the TI MSP430 and Atmel AVR processors does
this, using linker magic to find the boundaries of these areas.
The code, fortunately, is very short.  You can replace or remove
it if you really need to).

Some processors have much faster access to RAM memory on "page zero" 
than elsewhere, so you want to carefully control what goes there and
what doesn't.  

Interrupt vectors for a processor generally have to be placed at a 
fixed location.  If no interrupt vector handler is defined for a 
particular vector, you usually want it handled by a default (dummy)
handler rather than crashing.  Defining an interrupt handler to save
and restore registers properly is another common extension.

Some processors put code flash, RAM, and data eeprom in the same
address space (e.g. TI MSP430).  For this, you want to put everything
read-only into code flash if at all possible.  You might get 8k of
code flash, 256 bytes of RAM, and 256 bytes of data eeprom, plus
some I/O ports to control digital I/O, timers, analog/digital
conversion, system clock speed, programming eeprom, onboard temperature
sensor, etc.

Some processors have boundaries for code memory.  On many, if you
go over 64k (these are large processors:  many are limited to 4k
or less), you have to start worrying about what code goes in the
first 64k, and doing far calls between routines in different sections.

> By using "proper" static arrays, we lose out on the "shared storage" 
> benefit.  Writing for bare metal, hopefully one knows what one is doing.
> 
> Is this example silly?

Some "bare metal" processors have separate address spaces for code
flash, RAM, and data eeprom (e.g. Atmel ATMega328P, ATTiny85).
Placement of elements of the program in the proper space is critical.
You *CAN'T HAVE* a pointer that points into "either code or data,
depending".  You can't tell which it points to by examining bits.
Those of you familiar with PDP-11 "separate I and D" mode know what
I am referring to.  Both the code and data spaces start at 0x0000,
and pointers do not contain a bit to indicate whether code or data
is being addressed.  You have to know which one it is ahead of time
to know which instruction to use to fetch the data.  The only way
to read data from code flash is using a special machine instruction,
usually made accessible in C as a macro or inline function as an
extension.  So you have to *KNOW* whether a particular string
literal got put in code flash and adjust your code accordingly.

A compiler is likely to have an extension to put a string literal
in code flash.  GCC lets you attach attributes to typedefs.  However,
if you want to pass it to strcpy(), you have to have two different
versions of strcpy():  one that copies from code space to RAM, and
one that copies from RAM to RAM.  The same goes for puts().

Due to interests in protecting proprietary code programmed into the
chip, a fuse can be "blown" after programming which prohibits reading
from code flash except to execute code (or erase the chip entirely
- which means the proprietary code is now gone).  This may rule out
coding techniques such as "branch tables" or data constants (including
string literals) in the code section.  You don't *have* to use that
fuse, although it may be company policy if these chips are going
in your company product.

Many of the processors have a small amount (e.g. 256 bytes) of
non-volatile data memory.  It is particularly useful for
individual-chip-specific data such as MAC addresses and serial
numbers, calibration constants for temperature sensors or how far
your robot can reach, and storing stuff that has to survive power
cycling.  It typically can stand many (e.g. 100,000) re-programming
cycles, but trying to program it once a second will limit lifetime
to a little over a day.  It may or may not need a special function
(using a special machine instruction) to read from it (as opposed
to dereferencing pointers as though it were normal RAM or ROM).  It
may require you to "erase" a "page" of memory (e.g.  64 bytes)
before you can re-write it, and you might only get a few "pages",
so it's important to organize related things in memory together.

A "bare metal" chip may actually have "standard input" and "standard
output", at least in a debugging environment.  It might be a serial
port or USB interface acting like a serial port.  The chip may end
up using 25% of its code space generating a carefully-timed signal
that looks like the waveform of an actual hardware serial port.
Or it might send error codes in Morse code over an LED.

[toc] | [prev] | [next] | [standalone]


#6626

FromStephen Sprunk <stephen@sprunk.org>
Date2011-06-22 11:31 -0500
Message-ID<itt5da$4c3$1@dont-email.me>
In reply to#6597
On 22-Jun-11 03:28, Noob wrote:
> Keith Thompson wrote:
>> Even if you corrected the type mismatch by writing:
>>
>> char *s = "hello";
>>      *s = 'w';
>>
>> your program's behavior would be undefined.  s points to a string
>> literal (more precisely, it points to the first element of the static
>> array associated with the string literal), and any attempt to modify a
>> string literal has undefined behavior.
> 
> Since modifying a character string literal already has UB in
> the current standard, then why doesn't the next standard
> specify that string literal have type const char[] instead
> of just char[] ?

That has been proposed numerous times over the years, but it is always
shot down due to widespread fears of "const poisoning".  Frankly, I
think more use of const in C would be a good thing and eliminate many
lurking bugs, but to date ISO is unwilling to "break" code that assumes
string literals are not const but doesn't actually write to them.

S

-- 
Stephen Sprunk         "God does not play dice."  --Albert Einstein
CCIE #3723         "God is an inveterate gambler, and He throws the
K5SSS        dice at every possible opportunity." --Stephen Hawking

[toc] | [prev] | [next] | [standalone]


#6697

Fromgordonb.idn9q@burditt.org (Gordon Burditt)
Date2011-06-23 00:45 -0500
Message-ID<yp6dnQAIK81zT5_TnZ2dnUVZ_qWdnZ2d@posted.internetamerica>
In reply to#6626
> That has been proposed numerous times over the years, but it is always
> shot down due to widespread fears of "const poisoning".  Frankly, I
> think more use of const in C would be a good thing and eliminate many
> lurking bugs, but to date ISO is unwilling to "break" code that assumes
> string literals are not const but doesn't actually write to them.

What is the correct return type of these C functions (and I've
probably missed a few) which return a pointer into somewhere into
the string passed as a first argument, given that the first argument
might be a C string literal (which we're now changing to const) or
it might be a writable character array?  If it's a writable character
array, you might want to use the returned pointer to write into the
string.

	strchr()
	strrchr()
	strstr()
	strpbrk()

It seems you are stuck with one of several bad choices:
(1) dragging in C++ function overloading (does that even solve 
    the problem?  Can you overload on const/non-const arguments
    of otherwise the same type?),
(2) allowing these functions to return a non-const pointer to 
    non-writable data, thereby begging for bugs,
(3) giving an excellent excuse for "casting away constness" to 
    make use of a const pointer to writable data, thereby
    inviting ignoring of similar "casting away constness" without
    such a good excuse, which is begging for bugs,
(4) defining functions:
	char *strchr(char *s, int c);
and	const char * const_poisoned_strchr(const char *s, int c);
    which do the same thing, other than constness?
    This breaks existing code, at least with warnings.
    The C standard does not currently reserve symbols starting
    with const_poisoned_str* .

I can think of plenty of my own parsing functions that at least
potentially have the same issue:  given some input (which might be
a string literal of a default or a line out of some user's config
file) retrieve some part of the command (e.g. variable name or value
of a particular type) or NULL if the command is ill-formatted.

[toc] | [prev] | [next] | [standalone]


#6756

Frompacman@kosh.dhis.org (Alan Curry)
Date2011-06-23 20:08 +0000
Message-ID<iu06g6$9ku$1@speranza.aioe.org>
In reply to#6697
In article <yp6dnQAIK81zT5_TnZ2dnUVZ_qWdnZ2d@posted.internetamerica>,
Gordon Burditt <gordonb.idn9q@burditt.org> wrote:
>
>What is the correct return type of these C functions (and I've
>probably missed a few) which return a pointer into somewhere into
>the string passed as a first argument, given that the first argument
>might be a C string literal (which we're now changing to const) or
>it might be a writable character array?  If it's a writable character
>array, you might want to use the returned pointer to write into the
>string.
>
>	strchr()
>	strrchr()
>	strstr()
>	strpbrk()

All should return an integer offset from the beginning of the input string.
In their present form they are dangerous.

-- 
Alan Curry

[toc] | [prev] | [next] | [standalone]


#6778

FromStephen Sprunk <stephen@sprunk.org>
Date2011-06-23 22:40 -0500
Message-ID<iu10vs$76k$1@dont-email.me>
In reply to#6697
On 23-Jun-11 00:45, Gordon Burditt wrote:
>> That has been proposed numerous times over the years, but it is always
>> shot down due to widespread fears of "const poisoning".  Frankly, I
>> think more use of const in C would be a good thing and eliminate many
>> lurking bugs, but to date ISO is unwilling to "break" code that assumes
>> string literals are not const but doesn't actually write to them.
> 
> What is the correct return type of these C functions (and I've
> probably missed a few) which return a pointer into somewhere into
> the string passed as a first argument, given that the first argument
> might be a C string literal (which we're now changing to const) or
> it might be a writable character array?  If it's a writable character
> array, you might want to use the returned pointer to write into the
> string.
> 
> 	strchr()
> 	strrchr()
> 	strstr()
> 	strpbrk()
> 
> It seems you are stuck with one of several bad choices:
> (1) dragging in C++ function overloading (does that even solve 
>     the problem?  Can you overload on const/non-const arguments
>     of otherwise the same type?),

AIUI, you can.  I see the problem, though; in fact, while researching
that question, one page I found actually listed the various overloaded
forms of strchr() offered by one compiler.

If one weren't to add function overloading (which has its own appeal),
the only solution would be to deprecate those functions and design
replacements with a const-friendly interface.  However, that would break
so much code that it's simply not feasible.

S

-- 
Stephen Sprunk         "God does not play dice."  --Albert Einstein
CCIE #3723         "God is an inveterate gambler, and He throws the
K5SSS        dice at every possible opportunity." --Stephen Hawking

[toc] | [prev] | [next] | [standalone]


#6779

FromIan Collins <ian-news@hotmail.com>
Date2011-06-24 15:46 +1200
Message-ID<96ifliFmo4U6@mid.individual.net>
In reply to#6778
On 06/24/11 03:40 PM, Stephen Sprunk wrote:
> On 23-Jun-11 00:45, Gordon Burditt wrote:
>>> That has been proposed numerous times over the years, but it is always
>>> shot down due to widespread fears of "const poisoning".  Frankly, I
>>> think more use of const in C would be a good thing and eliminate many
>>> lurking bugs, but to date ISO is unwilling to "break" code that assumes
>>> string literals are not const but doesn't actually write to them.
>>
>> What is the correct return type of these C functions (and I've
>> probably missed a few) which return a pointer into somewhere into
>> the string passed as a first argument, given that the first argument
>> might be a C string literal (which we're now changing to const) or
>> it might be a writable character array?  If it's a writable character
>> array, you might want to use the returned pointer to write into the
>> string.
>>
>> 	strchr()
>> 	strrchr()
>> 	strstr()
>> 	strpbrk()
>>
>> It seems you are stuck with one of several bad choices:
>> (1) dragging in C++ function overloading (does that even solve
>>      the problem?  Can you overload on const/non-const arguments
>>      of otherwise the same type?),
>
> AIUI, you can.  I see the problem, though; in fact, while researching
> that question, one page I found actually listed the various overloaded
> forms of strchr() offered by one compiler.

The C++ standard replaces the C strchr() with two overloads:

const char* strchr(const char* s, int c);
       char* strchr(      char* s, int c);

-- 
Ian Collins

[toc] | [prev] | [next] | [standalone]


#6833

FromStephen Sprunk <stephen@sprunk.org>
Date2011-06-24 09:24 -0500
Message-ID<iu26ni$rjm$1@dont-email.me>
In reply to#6779
On 23-Jun-11 22:46, Ian Collins wrote:
> On 06/24/11 03:40 PM, Stephen Sprunk wrote:
>> On 23-Jun-11 00:45, Gordon Burditt wrote:
>>>> That has been proposed numerous times over the years, but it is always
>>>> shot down due to widespread fears of "const poisoning".  Frankly, I
>>>> think more use of const in C would be a good thing and eliminate many
>>>> lurking bugs, but to date ISO is unwilling to "break" code that assumes
>>>> string literals are not const but doesn't actually write to them.
>>>
>>> What is the correct return type of these C functions (and I've
>>> probably missed a few) which return a pointer into somewhere into
>>> the string passed as a first argument, given that the first argument
>>> might be a C string literal (which we're now changing to const) or
>>> it might be a writable character array?  If it's a writable character
>>> array, you might want to use the returned pointer to write into the
>>> string.
>>>
>>>     strchr()
>>>     strrchr()
>>>     strstr()
>>>     strpbrk()
>>>
>>> It seems you are stuck with one of several bad choices:
>>> (1) dragging in C++ function overloading (does that even solve
>>>      the problem?  Can you overload on const/non-const arguments
>>>      of otherwise the same type?),
>>
>> AIUI, you can.  I see the problem, though; in fact, while researching
>> that question, one page I found actually listed the various overloaded
>> forms of strchr() offered by one compiler.
> 
> The C++ standard replaces the C strchr() with two overloads:
> 
> const char* strchr(const char* s, int c);
>       char* strchr(      char* s, int c);

Compare to the only option C provides:

char *strchr(const char *s, int c);

This takes a const or non-const argument but always returns a non-const
pointer; the potential loss of const-ness invites bugs.  Thanks to
overloading, the C++ version is able to return a pointer that matches
the const-ness of its argument, preventing bugs.

S

-- 
Stephen Sprunk         "God does not play dice."  --Albert Einstein
CCIE #3723         "God is an inveterate gambler, and He throws the
K5SSS        dice at every possible opportunity." --Stephen Hawking

[toc] | [prev] | [next] | [standalone]


#7613

FromShao Miller <sha0.miller@gmail.com>
Date2011-07-04 18:00 -0400
Message-ID<iutd6j$e7o$1@dont-email.me>
In reply to#6833
On 6/24/2011 10:24, Stephen Sprunk wrote:
>>
>> The C++ standard replaces the C strchr() with two overloads:
>>
>> const char* strchr(const char* s, int c);
>>        char* strchr(      char* s, int c);
>
> Compare to the only option C provides:
>
> char *strchr(const char *s, int c);
>
> This takes a const or non-const argument but always returns a non-const
> pointer; the potential loss of const-ness invites bugs.  Thanks to
> overloading, the C++ version is able to return a pointer that matches
> the const-ness of its argument, preventing bugs.

A fellow yesterday advised of another strategy, using a GCC extension:

   #define strchr(s, c) ((__typeof__(s)) (strchr((s), (c)))

That is, casting the result to the original type of 's'.  Heheheh.

[toc] | [prev] | [next] | [standalone]


#7657

FromDr Nick <3-nospam@temporary-address.org.uk>
Date2011-07-05 07:45 +0100
Message-ID<87ei25ns3h.fsf@temporary-address.org.uk>
In reply to#7613
Shao Miller <sha0.miller@gmail.com> writes:

> On 6/24/2011 10:24, Stephen Sprunk wrote:
>>>
>>> The C++ standard replaces the C strchr() with two overloads:
>>>
>>> const char* strchr(const char* s, int c);
>>>        char* strchr(      char* s, int c);
>>
>> Compare to the only option C provides:
>>
>> char *strchr(const char *s, int c);
>>
>> This takes a const or non-const argument but always returns a non-const
>> pointer; the potential loss of const-ness invites bugs.  Thanks to
>> overloading, the C++ version is able to return a pointer that matches
>> the const-ness of its argument, preventing bugs.
>
> A fellow yesterday advised of another strategy, using a GCC extension:
>
>   #define strchr(s, c) ((__typeof__(s)) (strchr((s), (c)))
>
> That is, casting the result to the original type of 's'.  Heheheh.

That's either very neat or unutterably ghastly.  I'm still thinking
about which it is.
-- 
Online waterways route planner            | http://canalplan.eu
Plan trips, see photos, check facilities  | http://canalplan.org.uk

[toc] | [prev] | [next] | [standalone]


#7670

FromHarald van Dijk <truedfx@gmail.com>
Date2011-07-05 10:39 -0700
Message-ID<cea27845-0ef7-4afe-aba3-d1376846fb05@u2g2000yqb.googlegroups.com>
In reply to#7657
On Jul 5, 7:45 am, Dr Nick <3-nos...@temporary-address.org.uk> wrote:
> Shao Miller <sha0.mil...@gmail.com> writes:
> > A fellow yesterday advised of another strategy, using a GCC extension:
>
> >   #define strchr(s, c) ((__typeof__(s)) (strchr((s), (c)))
>
> > That is, casting the result to the original type of 's'.  Heheheh.
>
> That's either very neat or unutterably ghastly.  I'm still thinking
> about which it is.

I'm going for ghastly, because it gives an error when s is an array,
and it gives the wrong result type when s is a pointer to (const) void.

[toc] | [prev] | [next] | [standalone]


#7672

FromShao Miller <sha0.miller@gmail.com>
Date2011-07-05 14:09 -0400
Message-ID<iuvjvv$2oh$1@dont-email.me>
In reply to#7670
On 7/5/2011 13:39, Harald van Dijk wrote:
> On Jul 5, 7:45 am, Dr Nick<3-nos...@temporary-address.org.uk>  wrote:
>> Shao Miller<sha0.mil...@gmail.com>  writes:
>>> A fellow yesterday advised of another strategy, using a GCC extension:
>>
>>>    #define strchr(s, c) ((__typeof__(s)) (strchr((s), (c)))
>>
>>> That is, casting the result to the original type of 's'.  Heheheh.
>>
>> That's either very neat or unutterably ghastly.  I'm still thinking
>> about which it is.
>
> I'm going for ghastly, because it gives an error when s is an array,
> and it gives the wrong result type when s is a pointer to (const) void.

(Note I had missed a right parenthesis at the end.)

That rings quite true. :)

Hmmm...  I was actually just guessing at the macro based on what the 
fellow had said, but considering your array note, perhaps it was more like:

   #define strchr(s, c) (*((__typeof__(s) *) (strchr((s), (c)))))

It might be interesting if there was a '__constof__(type-name)' and/or 
'__constof__(object)' that could expand to 'const' or nothing, as 
appropriate.

   const char * foo;
   /* The next type is 'const char' */
   typedef __constof__(*foo) char foo_base_t;
   /* The next type is silly */
   typedef int * __constof__(foo_base_t) bar;

Uhhh... :S

   #define strchr(s, c) ((__constof__(*(s)) char *) (strchr((s), (c))))

[toc] | [prev] | [next] | [standalone]


#7870

FromPhil Carmody <thefatphil_demunged@yahoo.co.uk>
Date2011-07-07 21:56 +0300
Message-ID<87d3hl6ht7.fsf@bazspaz.fatphil.org>
In reply to#7672
卨慯⁍楬汥爠㱳桡〮浩汬敲䁧浡楬⹣潭㸠睲楴敳㨍਍ਾ⁏渠㜯㔯㈰ㄱ‱㌺㌹Ⱐ䡡牡汤⁶慮⁄ij欠睲潴攺ഊ㸠㸠佮⁊畬‵Ⱐ㜺㐵⁡洬⁄爠乩捫㰳⵮潳⸮⹀瑥浰潲慲礭慤摲敳献潲朮畫㸠⁷牯瑥㨍ਾ‾㸠卨慯⁍楬汥爼獨愰⹭楬⸮⹀杭慩氮捯派†睲楴敳㨍ਾ‾㸾⁁⁦敬汯眠祥獴敲摡礠慤癩獥搠潦⁡湯瑨敲⁳瑲慴敧礬⁵獩湧⁡⁇䍃⁥硴敮獩潮㨍ਾ‾㸍ਾ‾㸾††⍤敦楮攠獴牣桲⡳Ⱐ挩
⡟彴祰敯晟弨猩⤠⡳瑲捨爨⡳⤬
挩⤩ഊ㸠㸾ഊ㸠㸾㸠周慴⁩猬⁣慳瑩湧⁴桥⁲敳畬琠瑯⁴桥物杩湡氠瑹灥映❳✮†䡥桥桥栮ഊ㸠㸾ഊ㸠㸾⁔桡琧猠敩瑨敲⁶敲礠湥慴爠畮畴瑥牡扬礠杨慳瑬礮†䤧洠獴楬氠瑨楮歩湧ഊ㸠㸾⁡扯畴⁷桩捨⁩琠楳⸍ਾ‾ഊ㸠㸠䤧洠杯楮朠景爠杨慳瑬礬⁢散慵獥⁩琠杩癥猠慮⁥牲潲⁷桥渠猠楳⁡渠慲牡礬ഊ㸠㸠慮搠楴⁧楶敳⁴桥⁷牯湧⁲敳畬琠瑹灥⁷桥渠猠楳⁡⁰潩湴敲⁴漠⡣潮獴⤠癯楤⸍ਾ‍ਾ
乯瑥⁉⁨慤楳獥搠愠物杨琠灡牥湴桥獩猠慴⁴桥⁥湤⸩ഊ㸠ഊ㸠周慴⁲楮杳ⁱ畩瑥⁴牵攮›⤍ਾ‍ਾ⁈浭洮⸮†䤠睡猠慣瑵慬汹畳琠杵敳獩湧⁡琠瑨攠浡捲漠扡獥搠潮⁷桡琠瑨攍ਾ⁦敬汯眠桡搠獡楤Ⱐ扵琠捯湳楤敲楮朠祯畲⁡牲慹潴攬⁰敲桡灳⁩琠睡猠浯牥ഊ㸠汩步㨍ਾ‍ਾ††⍤敦楮攠獴牣桲⡳Ⱐ挩
⨨⡟彴祰敯晟弨猩‪⤠⡳瑲捨爨⡳⤬
挩⤩⤩ഊഊ䡯眠慢潵琠橵獴㨍਍ਣ摥晩湥⁳瑲捨爨猬⁣⤠⠨彟瑹灥潦彟⠦⩳⤩
獴牣桲⠨猩Ⱐ⡣⤩⤩ഊഊ㼠ഊഊ㸠䥴楧桴⁢攠楮瑥牥獴楮朠楦⁴桥牥⁷慳⁡‧彟捯湳瑯晟弨瑹灥⵮慭攩✠慮搯潲ഊ㸠❟彣潮獴潦彟⡯扪散琩✠瑨慴⁣潵汤⁥硰慮搠瑯‧捯湳琧爠湯瑨楮本⁡猍ਾ⁡灰牯灲楡瑥⸍਍੔桡琠䤠汩步⸠䄠汯琮⁇整⁩琠楮⁇䍃Ⱐ慮搠䤧汬⁢攠慮⁥慲汹⁡摯灴敲⸍਍੐桩氍ਭⴠഊ≁琠汥慳琠祯甠歮潷⁷桥牥⁹潵⁡牥⁷楴栠䵩捲潳潦琮∍ਢ呲略⸠䤠橵獴⁷楳栠䤧搠扲潵杨琠愠灡摤汥⸢‭ⴠ䵡瑴桥眠噥牮潮

[toc] | [prev] | [next] | [standalone]


#7910

FromPhil Carmody <thefatphil_demunged@yahoo.co.uk>
Date2011-07-08 02:46 +0300
Message-ID<87vcvd4ptr.fsf@bazspaz.fatphil.org>
In reply to#7870
Phil Carmody <thefatphil_demunged@yahoo.co.uk> writes:
> �⁍�����〮������⹣������ਾ⁏���㈰ㄱ‱㌺㌹Ⱐ���⁶�⁄ij����ਾ‾⁏����‷���Ⱐ�⁎��㌭��⸮�����ⵡ���⹯�⹵�†���ਾ‾���⁍�����⹭�⸮⹀�����†�����������⁹����⁡������������Ⱐ�����������ਾ‾����†‣���⁳����⁣⤠⠨�����⡳⤩
���⠨�Ⱐ⡣⤩⤊��ਾ‾�⁔���Ⱐ���������⁴�������⁴���‧�⸠⁈���⸊��ਾ‾���❳⁥��������⁵�����⁧���⸠⁉❭⁳��⁴������⁡��⁷��⁩��⸊���������������⁢���⁩�����⁥��⁷����⁡����ਾ‾⁡�⁩������������⁴����⁳⁩�������
���⁶��ਾ �⡎��������⁡⁲��⁰�����⁡�����⤊�ਾ⁔����������⸠�ਾ ���⸮⸠⁉⁷�⁡������⁧�����⁴���⁢�����⁴�ਾ⁦�������Ⱐ����������⁡����⁰���⁩�����ਾ��ਾ �†‣���⁳����⁣⤠⠪⠨�����⡳⤠⨩
���⠨�Ⱐ⡣⤩⤩⤊ੈ�⁡����ਊ⍤������⡳Ⱐ�
⡟�����☪�⤠⡳���⡳⤬
�⤩⤊ਿ ਾ⁉�����⁩�����⁩�������❟�����⡴����⤧⁡�⽯��❟�����⡯���✠��⁣��⁥����‧��������⁡��������ਊ��⁉��⁁�⸠���⁩���⁡�⁉❬��⁡��������ਊ��ਭⴠਢ���⁹������������⁍����⸢ਢ��⸠���⁷������������⸢‭ⴠ�������

No idea what happened there, that's all "?"s to me. I certainly never consciously chose
Content-Type: text/plain; charset=utf-16be
Google groups, no matter how much it sucks, shows that there's a post hidden behind that noise:
http://groups.google.com/group/comp.lang.c/msg/4bbd1eab45333db5

-- 
"At least you know where you are with Microsoft."
"True. I just wish I'd brought a paddle." -- Matthew Vernon

[toc] | [prev] | [next] | [standalone]


#7916

FromShao Miller <sha0.miller@gmail.com>
Date2011-07-07 22:26 -0400
Message-ID<iv5ppf$ce8$1@dont-email.me>
In reply to#7910
On 7/7/2011 19:46, Phil Carmody wrote:
> Phil Carmody<thefatphil_demunged@yahoo.co.uk>  writes:
>> [...uhh...]
>
> No idea what happened there, that's all "?"s to me. I certainly never consciously chose
> Content-Type: text/plain; charset=utf-16be
> Google groups, no matter how much it sucks, shows that there's a post hidden behind that noise:
> http://groups.google.com/group/comp.lang.c/msg/4bbd1eab45333db5
>

Doubly-odd.  It showed up weird in Thunderbird, so I went to Google 
Groups to confirm.  That's how I saw it there, too.  I actually replied 
from Google Groups as Thunderbird wouldn't send my response (due to the 
quoting?). :S  Anyway...

[toc] | [prev] | [next] | [standalone]


Page 2 of 3 — ← Prev page 1 [2] 3  Next page →

Back to top | Article view | comp.lang.c


csiph-web