Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.c > #6574 > unrolled thread
| Started by | yugandhar <nospam@nospam.com> |
|---|---|
| First post | 2011-06-21 21:49 +0000 |
| Last post | 2011-06-21 21:29 -0500 |
| Articles | 20 on this page of 53 — 20 participants |
Back to article view | Back to comp.lang.c
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 →
| From | Ian Collins <ian-news@hotmail.com> |
|---|---|
| Date | 2011-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]
| From | Shao Miller <sha0.miller@gmail.com> |
|---|---|
| Date | 2011-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]
| From | Keith Thompson <kst-u@mib.org> |
|---|---|
| Date | 2011-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]
| From | Ian Collins <ian-news@hotmail.com> |
|---|---|
| Date | 2011-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]
| From | Shao Miller <sha0.miller@gmail.com> |
|---|---|
| Date | 2011-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]
| From | Tim Rentsch <txr@alumni.caltech.edu> |
|---|---|
| Date | 2011-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]
| From | gordonb.5qick@burditt.org (Gordon Burditt) |
|---|---|
| Date | 2011-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]
| From | Stephen Sprunk <stephen@sprunk.org> |
|---|---|
| Date | 2011-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]
| From | gordonb.idn9q@burditt.org (Gordon Burditt) |
|---|---|
| Date | 2011-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]
| From | pacman@kosh.dhis.org (Alan Curry) |
|---|---|
| Date | 2011-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]
| From | Stephen Sprunk <stephen@sprunk.org> |
|---|---|
| Date | 2011-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]
| From | Ian Collins <ian-news@hotmail.com> |
|---|---|
| Date | 2011-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]
| From | Stephen Sprunk <stephen@sprunk.org> |
|---|---|
| Date | 2011-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]
| From | Shao Miller <sha0.miller@gmail.com> |
|---|---|
| Date | 2011-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]
| From | Dr Nick <3-nospam@temporary-address.org.uk> |
|---|---|
| Date | 2011-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]
| From | Harald van Dijk <truedfx@gmail.com> |
|---|---|
| Date | 2011-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]
| From | Shao Miller <sha0.miller@gmail.com> |
|---|---|
| Date | 2011-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]
| From | Phil Carmody <thefatphil_demunged@yahoo.co.uk> |
|---|---|
| Date | 2011-07-07 21:56 +0300 |
| Message-ID | <87d3hl6ht7.fsf@bazspaz.fatphil.org> |
| In reply to | #7672 |
卨慯⁍楬汥爠㱳桡〮浩汬敲䁧浡楬潭㸠睲楴敳㨍ਾ⁏渠㜯㔯㈰ㄱ‱㌺㌹Ⱐ䡡牡汤⁶慮⁄ij欠睲潴攺ഊ㸠㸠佮⁊畬‵Ⱐ㜺㐵洬⁄爠乩捫㰳潳⸮⹀瑥浰潲慲礭慤摲敳献潲朮畫㸠⁷牯瑥㨍ਾ‾㸠卨慯⁍楬汥爼獨愰楬⸮⹀杭慩氮捯派†睲楴敳㨍ਾ‾㸾⁁敬汯眠祥獴敲摡礠慤癩獥搠潦湯瑨敲瑲慴敧礬⁵獩湧⁇䍃硴敮獩潮㨍ਾ‾㸍ਾ‾㸾††⍤敦楮攠獴牣桲⡳Ⱐ挩 ⡟彴祰敯晟弨猩⤠⡳瑲捨爨⡳⤬ 挩⤩ഊ㸠㸾ഊ㸠㸾㸠周慴猬慳瑩湧⁴桥敳畬琠瑯⁴桥物杩湡氠瑹灥映❳✮†䡥桥桥栮ഊ㸠㸾ഊ㸠㸾⁔桡琧猠敩瑨敲⁶敲礠湥慴爠畮畴瑥牡扬礠杨慳瑬礮†䤧洠獴楬氠瑨楮歩湧ഊ㸠㸾扯畴⁷桩捨琠楳⸍ਾ‾ഊ㸠㸠䤧洠杯楮朠景爠杨慳瑬礬散慵獥琠杩癥猠慮牲潲⁷桥渠猠楳渠慲牡礬ഊ㸠㸠慮搠楴楶敳⁴桥⁷牯湧敳畬琠瑹灥⁷桥渠猠楳⁰潩湴敲⁴漠⡣潮獴⤠癯楤⸍ਾਾ 乯瑥⁉慤楳獥搠愠物杨琠灡牥湴桥獩猠慴⁴桥湤⸩ഊ㸠ഊ㸠周慴楮杳ⁱ畩瑥⁴牵攮›⤍ਾਾ⁈浭洮⸮†䤠睡猠慣瑵慬汹畳琠杵敳獩湧琠瑨攠浡捲漠扡獥搠潮⁷桡琠瑨攍ਾ敬汯眠桡搠獡楤Ⱐ扵琠捯湳楤敲楮朠祯畲牲慹潴攬⁰敲桡灳琠睡猠浯牥ഊ㸠汩步㨍ਾਾ††⍤敦楮攠獴牣桲⡳Ⱐ挩 ⨨⡟彴祰敯晟弨猩⤠⡳瑲捨爨⡳⤬ 挩⤩⤩ഊഊ䡯眠慢潵琠橵獴㨍ਣ摥晩湥瑲捨爨猬⤠⠨彟瑹灥潦彟⠦⩳⤩ 獴牣桲⠨猩Ⱐ⡣⤩⤩ഊഊ㼠ഊഊ㸠䥴楧桴攠楮瑥牥獴楮朠楦⁴桥牥⁷慳‧彟捯湳瑯晟弨瑹灥慭攩✠慮搯潲ഊ㸠❟彣潮獴潦彟⡯扪散琩✠瑨慴潵汤硰慮搠瑯‧捯湳琧爠湯瑨楮本猍ਾ灰牯灲楡瑥⸍桡琠䤠汩步⸠䄠汯琮⁇整琠楮⁇䍃Ⱐ慮搠䤧汬攠慮慲汹摯灴敲⸍桩氍ਭⴠഊ≁琠汥慳琠祯甠歮潷⁷桥牥⁹潵牥⁷楴栠䵩捲潳潦琮∍ਢ呲略⸠䤠橵獴⁷楳栠䤧搠扲潵杨琠愠灡摤汥⸢ⴠ䵡瑴桥眠噥牮潮
[toc] | [prev] | [next] | [standalone]
| From | Phil Carmody <thefatphil_demunged@yahoo.co.uk> |
|---|---|
| Date | 2011-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]
| From | Shao Miller <sha0.miller@gmail.com> |
|---|---|
| Date | 2011-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