Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.c > #18954 > unrolled thread
| Started by | mathog <dmathog@gmail.com> |
|---|---|
| First post | 2012-03-23 08:40 -0700 |
| Last post | 2012-04-27 08:31 -0700 |
| Articles | 20 on this page of 46 — 17 participants |
Back to article view | Back to comp.lang.c
c99 and the lack of warnings when int operations are applied to a bool mathog <dmathog@gmail.com> - 2012-03-23 08:40 -0700
Re: c99 and the lack of warnings when int operations are applied to a bool James Kuyper <jameskuyper@verizon.net> - 2012-03-23 12:07 -0400
Re: c99 and the lack of warnings when int operations are applied to a bool jacob navia <jacob@spamsink.net> - 2012-03-23 21:45 +0100
Re: c99 and the lack of warnings when int operations are applied to a bool Robert Wessel <robertwessel2@yahoo.com> - 2012-03-23 17:17 -0500
Re: c99 and the lack of warnings when int operations are applied to a bool jacob navia <jacob@spamsink.net> - 2012-03-23 23:29 +0100
Re: c99 and the lack of warnings when int operations are applied to a bool Ian Collins <ian-news@hotmail.com> - 2012-03-24 11:48 +1300
Re: c99 and the lack of warnings when int operations are applied to a bool jacob navia <jacob@spamsink.net> - 2012-03-24 23:47 +0100
Re: c99 and the lack of warnings when int operations are applied to a bool Willem <willem@toad.stack.nl> - 2012-03-25 09:05 +0000
Re: c99 and the lack of warnings when int operations are applied to a bool "BartC" <bc@freeuk.com> - 2012-03-25 11:30 +0100
Re: c99 and the lack of warnings when int operations are applied to a bool Ben Bacarisse <ben.usenet@bsb.me.uk> - 2012-03-25 21:05 +0100
Re: c99 and the lack of warnings when int operations are applied to a bool Lowell Gilbert <lgusenet@be-well.ilk.org> - 2012-03-25 16:15 -0400
Re: c99 and the lack of warnings when int operations are applied to a bool Ben Bacarisse <ben.usenet@bsb.me.uk> - 2012-03-25 22:14 +0100
Re: c99 and the lack of warnings when int operations are applied to a bool James Kuyper <jameskuyper@verizon.net> - 2012-03-25 23:46 -0400
Re: c99 and the lack of warnings when int operations are applied to a bool Ben Bacarisse <ben.usenet@bsb.me.uk> - 2012-03-26 12:05 +0100
Re: c99 and the lack of warnings when int operations are applied to a bool Lowell Gilbert <lgusenet@be-well.ilk.org> - 2012-03-26 15:22 -0400
Re: c99 and the lack of warnings when int operations are applied to a bool Gareth Owen <gwowen@gmail.com> - 2012-03-25 11:44 +0100
Re: c99 and the lack of warnings when int operations are applied to a bool Ben Bacarisse <ben.usenet@bsb.me.uk> - 2012-03-25 13:06 +0100
Re: c99 and the lack of warnings when int operations are applied to a bool Tim Rentsch <txr@alumni.caltech.edu> - 2012-03-27 11:12 -0700
Re: c99 and the lack of warnings when int operations are applied to a bool Robert Wessel <robertwessel2@yahoo.com> - 2012-03-24 01:15 -0500
Re: c99 and the lack of warnings when int operations are applied to a bool jacob navia <jacob@spamsink.net> - 2012-03-24 23:29 +0100
Re: c99 and the lack of warnings when int operations are applied to a bool mathog <dmathog@gmail.com> - 2012-03-27 09:53 -0700
Re: c99 and the lack of warnings when int operations are applied to a bool Keith Thompson <kst-u@mib.org> - 2012-03-27 11:07 -0700
Re: c99 and the lack of warnings when int operations are applied to a bool James Kuyper <jameskuyper@verizon.net> - 2012-03-27 14:16 -0400
Re: c99 and the lack of warnings when int operations are applied to a bool Eric Sosman <esosman@ieee-dot-org.invalid> - 2012-04-26 07:57 -0400
Re: c99 and the lack of warnings when int operations are applied to a bool jacob navia <jacob@spamsink.net> - 2012-04-26 14:08 +0200
Re: c99 and the lack of warnings when int operations are applied to a bool James Kuyper <jameskuyper@verizon.net> - 2012-04-26 09:09 -0400
Re: c99 and the lack of warnings when int operations are applied to a bool Eric Sosman <esosman@ieee-dot-org.invalid> - 2012-04-26 21:29 -0400
Re: c99 and the lack of warnings when int operations are applied to a bool James Kuyper <jameskuyper@verizon.net> - 2012-04-26 21:58 -0400
Re: c99 and the lack of warnings when int operations are applied to a bool Eric Sosman <esosman@ieee-dot-org.invalid> - 2012-04-26 22:32 -0400
Re: c99 and the lack of warnings when int operations are applied to a bool James Kuyper <jameskuyper@verizon.net> - 2012-04-27 06:31 -0400
Re: c99 and the lack of warnings when int operations are applied to a bool Lanarcam <lanarcam1@yahoo.fr> - 2012-04-27 19:26 +0200
Re: c99 and the lack of warnings when int operations are applied to a bool Keith Thompson <kst-u@mib.org> - 2012-04-27 11:28 -0700
Re: c99 and the lack of warnings when int operations are applied to a bool Lanarcam <lanarcam1@yahoo.fr> - 2012-04-27 20:51 +0200
Re: c99 and the lack of warnings when int operations are applied to a bool ImpalerCore <jadill33@gmail.com> - 2012-04-27 12:17 -0700
Re: c99 and the lack of warnings when int operations are applied to a bool Jens Gustedt <jens.gustedt@loria.fr> - 2012-04-28 09:17 +0200
Re: c99 and the lack of warnings when int operations are applied to a bool Keith Thompson <kst-u@mib.org> - 2012-04-28 13:26 -0700
Re: c99 and the lack of warnings when int operations are applied to a bool Willem <willem@toad.stack.nl> - 2012-04-27 18:11 +0000
Re: c99 and the lack of warnings when int operations are applied to a bool ImpalerCore <jadill33@gmail.com> - 2012-04-27 12:05 -0700
Re: c99 and the lack of warnings when int operations are applied to a bool James Kuyper <jameskuyper@verizon.net> - 2012-04-27 15:32 -0400
Re: c99 and the lack of warnings when int operations are applied to a bool Willem <willem@toad.stack.nl> - 2012-04-27 20:16 +0000
Re: c99 and the lack of warnings when int operations are applied to a bool James Kuyper <jameskuyper@verizon.net> - 2012-04-27 16:45 -0400
Re: c99 and the lack of warnings when int operations are applied to a bool Rui Maciel <rui.maciel@gmail.com> - 2012-04-27 21:26 +0100
Re: c99 and the lack of warnings when int operations are applied to a bool Eric Sosman <esosman@ieee-dot-org.invalid> - 2012-04-27 21:18 -0400
Re: c99 and the lack of warnings when int operations are applied to a bool Rui Maciel <rui.maciel@gmail.com> - 2012-04-27 21:33 +0100
Re: c99 and the lack of warnings when int operations are applied to a bool Keith Thompson <kst-u@mib.org> - 2012-04-27 15:36 -0700
Re: c99 and the lack of warnings when int operations are applied to a bool ImpalerCore <jadill33@gmail.com> - 2012-04-27 08:31 -0700
Page 2 of 3 — ← Prev page 1 [2] 3 Next page →
| From | mathog <dmathog@gmail.com> |
|---|---|
| Date | 2012-03-27 09:53 -0700 |
| Message-ID | <jksrbo$p2a$1@dont-email.me> |
| In reply to | #18971 |
jacob navia wrote: > I think you have an important point here. Bool is a logical value, not > an arithmetic or floating point value. There is no sense in taking the > square root of a bool, nor there is any sense in dividing a bool by any > integer: the result is always zero unless the other number is 1. My point exactly, even if a bool in some implementation is stored more or less the same way as an integer type, none of the integer operations should be applicable to it. The problem is clearer if one thinks of the values of the bool as "True" and "False", as opposed to 0 or 1. None of these have any meaning: True++ True+10 True/True True+False etc. Code that performed those operations is broken. Yet all of those are accepted without a hiccup at present. This is different from the use of an int as a logical value, where, since in some contexts the variable might be used as an integer, and others as a logical value, all of the above are OK. Consider even a simple assignment: bool b; int i=25; b=i; is actually: b= (i ? True : False); and is not actually a direct assignment of the value of i to b. In order to avoid difficult to find programming mistakes the explicit cast should be required: b = (bool) i; and also going the other way i = (int) b; This would let the compiler do its job of finding suspect code. If the standard doesn't require it would still be a very useful compiler switch as something like: cc --req_cast_bool Does the standard say that these situations cannot generate a warning??? If not, then they should, at least optionally, as for instance if one used gcc's -Wall. Regards, David Mathog
[toc] | [prev] | [next] | [standalone]
| From | Keith Thompson <kst-u@mib.org> |
|---|---|
| Date | 2012-03-27 11:07 -0700 |
| Message-ID | <lnhax9hq8a.fsf@nuthaus.mib.org> |
| In reply to | #19077 |
mathog <dmathog@gmail.com> writes:
> jacob navia wrote:
>> I think you have an important point here. Bool is a logical value, not
>> an arithmetic or floating point value. There is no sense in taking the
>> square root of a bool, nor there is any sense in dividing a bool by any
>> integer: the result is always zero unless the other number is 1.
>
> My point exactly, even if a bool in some implementation is stored more
> or less the same way as an integer type, none of the integer operations
> should be applicable to it. The problem is clearer if one thinks of the
> values of the bool as "True" and "False", as opposed to 0 or 1. None of
> these have any meaning:
>
> True++
> True+10
> True/True
> True+False
> etc.
>
> Code that performed those operations is broken. Yet all of those are
> accepted without a hiccup at present. This is different from the use of
> an int as a logical value, where, since in some contexts the variable
> might be used as an integer, and others as a logical value, all of the
> above are OK.
>
> Consider even a simple assignment:
>
> bool b;
> int i=25;
> b=i;
>
> is actually:
>
> b= (i ? True : False);
>
> and is not actually a direct assignment of the value of i to b. In
> order to avoid difficult to find programming mistakes the explicit cast
> should be required:
>
> b = (bool) i;
>
> and also going the other way
>
> i = (int) b;
>
> This would let the compiler do its job of finding suspect code. If the
> standard doesn't require it would still be a very useful compiler switch
> as something like:
>
> cc --req_cast_bool
>
> Does the standard say that these situations cannot generate a warning???
> If not, then they should, at least optionally, as for instance if one
> used gcc's -Wall.
The standard *never* forbids warnings for anything. It specifies
constructs for which an implementation must issue a diagnostic,
which may be either a warning or a fatal error, and it specifies
exactly one case where a translation unit must be rejected (#error),
but compilers can issue any additional warnings they like.
There are languages in which bool, or Boolean, is a completely
seperate type. In Ada, for example, it's defined as an enumeration
type with some special properties (type Boolean is (False, True);),
and Ada enumeration types in general can't be mixed with integer
types. For example, there's no predefined addition operator for
Boolean, or for any other enumeration type.
C *currently* defines _Bool as an unsigned integer type that can
hold the values 0 and 1. There are some special rules regarding
conversions from other scalar types to _Bool, but you can do the
same implicit conversions between _Bool and any other arithmetic
type as you can for char, int, and so forth.
Personally, I like the Ada approach better. But I'm not sure it
would have been practical to use the same approach in C. It would
have required creating a whole new class of type, with _Bool as its
only member. If it's a scalar type, you'd have to add special-case
restrictions to forbid certain implicit conversions; otherwise
"_Bool b = 0; b += 2;" would be perfectly legal (as it is now).
It's almost inevitable that some of those restrictions would prevent
programmers from doing some perfectly sensible things.
If you don't allow 0 and 1 to be assigned to a _Bool object,
requiring literal false and true instead, then you have an elementary
type for which 0 is not a valid value. Currently, this:
some_type obj = { 0 };
is valid for any object type; would it become invalid if some_type
is a structure one of whose members is a structure containing a
_Bool member? Or would you have to permit 0 and 1 to be boolean
constants, just as 0 is a pointer constant?
What would be the required type of the condition in an if statement?
Forbidding integer, floating-point, and pointer expressions would
break most existing C programs. Obviously we need to permit _Bool
conditions. Is that a special case? Do we permit an implicit
conversion from any scalar type to _Bool? Does that conversion
occur everywhere (as it does now), or only in an expression used
as a condition?
I'm not saying that it would have been impossible to add a boolean
type that behaves as suggested, but I think it would have required
a lot more work to define it consistently, and I rather doubt that
the C committee (which consists of volunteers, remember) could have
afforded the time to do it. They might have considered it if there
were existing practice, or if someone had submitted a proposal,
but as far as I know nobody did.
And I suggest that it's too late to fix it now without breaking
existing code. There is existing code that applies the ++ operator
to boolean objects, expecting them to be set to a true value (that
goes back before C99, when the "boolean" object was probably an int).
If I were designing a C-like language from scratch today, I'd
probably make bool a distinct type without implicit conversions, and
require "if (ptr != NULL)" rather than "if (ptr)", and "if (n != 0)"
rather than "if (n)". But we no longer have the luxury of doing that
-- and I'm sure a lot of people wouldn't like that approach anyway.
--
Keith Thompson (The_Other_Keith) kst-u@mib.org <http://www.ghoti.net/~kst>
Will write code for food.
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
[toc] | [prev] | [next] | [standalone]
| From | James Kuyper <jameskuyper@verizon.net> |
|---|---|
| Date | 2012-03-27 14:16 -0400 |
| Message-ID | <4F7203FC.2080305@verizon.net> |
| In reply to | #19077 |
On 03/27/2012 12:53 PM, mathog wrote: ... > My point exactly, even if a bool in some implementation is stored more > or less the same way as an integer type, none of the integer operations > should be applicable to it. The problem is clearer if one thinks of the > values of the bool as "True" and "False", as opposed to 0 or 1. None of > these have any meaning: > > True++ > True+10 > True/True > True+False > etc. > > Code that performed those operations is broken. Yet all of those are > accepted without a hiccup at present. This is different from the use of > an int as a logical value, where, since in some contexts the variable > might be used as an integer, and others as a logical value, all of the > above are OK. > > Consider even a simple assignment: > > bool b; > int i=25; > b=i; > > is actually: > > b= (i ? True : False); > > and is not actually a direct assignment of the value of i to b. In > order to avoid difficult to find programming mistakes the explicit cast > should be required: > > b = (bool) i; > > and also going the other way > > i = (int) b; > > This would let the compiler do its job of finding suspect code. If the > standard doesn't require it would still be a very useful compiler switch > as something like: > > cc --req_cast_bool > > Does the standard say that these situations cannot generate a warning??? The standard never prohibits warnings, it only mandates diagnostic messages. A fully conforming compiler is free to warn about anything it's makers want it to warn about. It can warn about the fact that you used profanity in your program - it could also warn about the fact that you did NOT use profanity in your program. No diagnostic is mandated for any of the cases you describe, because _Bool values are implicitly promoted to 'int', for which all of those operations are permitted and reasonable. Whether the implicit promotion is reasonable is another question. > If not, then they should, at least optionally, as for instance if one > used gcc's -Wall. You can't ask gcc to warn if a _Bool value is used in an addition expression, because that never happens - the _Bool value is promoted to 'int' before it is added. You can ask the makers of gcc to implement a warning for all implicit conversions of _Bool to other types. No such conversion occurs in most contexts where use of a boolean value actually makes sense: sizeof, _Alignof, &&, ||, !, the left operand of ?:, simple assignment when the destination is of _Bool type, if(), while(), the second expression of for(), and the return statement of a function declared as returning _Bool. The main exceptions are ==, !=, and switch(), which all perform the integer promotions on _Bool values.
[toc] | [prev] | [next] | [standalone]
| From | Eric Sosman <esosman@ieee-dot-org.invalid> |
|---|---|
| Date | 2012-04-26 07:57 -0400 |
| Message-ID | <jnbd7q$17a$1@dont-email.me> |
| In reply to | #19077 |
On 3/27/2012 12:53 PM, mathog wrote:
> jacob navia wrote:
>
>> I think you have an important point here. Bool is a logical value, not
>> an arithmetic or floating point value. There is no sense in taking the
>> square root of a bool, nor there is any sense in dividing a bool by any
>> integer: the result is always zero unless the other number is 1.
>
> My point exactly, even if a bool in some implementation is stored more
> or less the same way as an integer type, none of the integer operations
> should be applicable to it.
bool expensive(), complicated(), long_winded();
switch (4*expensive() + 2*complicated() + long_winded()) {
case 0: ...
case 1: ...
case 2: ...
case 3: ...
case 4: ...
case 5: ...
case 6: ...
case 7: ...
}
I'll grant that this sort of situation doesn't arise all that often,
and I'll grant that there are other ways to write the logic (there's
usually more than one way to do something in C), but I think you're
going overboard in trying to legislate the pattern out of existence.
--
Eric Sosman
esosman@ieee-dot-org.invalid
[toc] | [prev] | [next] | [standalone]
| From | jacob navia <jacob@spamsink.net> |
|---|---|
| Date | 2012-04-26 14:08 +0200 |
| Message-ID | <jnbdqu$qr7$1@speranza.aioe.org> |
| In reply to | #19955 |
Le 26/04/12 13:57, Eric Sosman a écrit : > > bool expensive(), complicated(), long_winded(); With my proposal, your expression should be switch (4*(int)expensive() + 2*(int)complicated() + (int)long_winded()) An explicit cast makes the programmer intention clear.
[toc] | [prev] | [next] | [standalone]
| From | James Kuyper <jameskuyper@verizon.net> |
|---|---|
| Date | 2012-04-26 09:09 -0400 |
| Message-ID | <jnbhej$ovn$1@dont-email.me> |
| In reply to | #19955 |
On 04/26/2012 07:57 AM, Eric Sosman wrote:
> On 3/27/2012 12:53 PM, mathog wrote:
...
>> My point exactly, even if a bool in some implementation is stored more
>> or less the same way as an integer type, none of the integer operations
>> should be applicable to it.
>
> bool expensive(), complicated(), long_winded();
> switch (4*expensive() + 2*complicated() + long_winded()) {
> case 0: ...
> case 1: ...
> case 2: ...
> case 3: ...
> case 4: ...
> case 5: ...
> case 6: ...
> case 7: ...
> }
>
> I'll grant that this sort of situation doesn't arise all that often,
> and I'll grant that there are other ways to write the logic (there's
> usually more than one way to do something in C), but I think you're
> going overboard in trying to legislate the pattern out of existence.
If bool were a strictly logical type, on which no arithmetic could be
performed, that pattern would still be allowed, the syntax would just be
slightly more complicated:
(expensive()?4:0) + (complicated()?2:0) + (long_winded()?1:0)
--
James Kuyper
[toc] | [prev] | [next] | [standalone]
| From | Eric Sosman <esosman@ieee-dot-org.invalid> |
|---|---|
| Date | 2012-04-26 21:29 -0400 |
| Message-ID | <jncspr$on8$1@dont-email.me> |
| In reply to | #19957 |
On 4/26/2012 9:09 AM, James Kuyper wrote:
> On 04/26/2012 07:57 AM, Eric Sosman wrote:
>> On 3/27/2012 12:53 PM, mathog wrote:
> ...
>>> My point exactly, even if a bool in some implementation is stored more
>>> or less the same way as an integer type, none of the integer operations
>>> should be applicable to it.
>>
>> bool expensive(), complicated(), long_winded();
>> switch (4*expensive() + 2*complicated() + long_winded()) {
>> case 0: ...
>> case 1: ...
>> case 2: ...
>> case 3: ...
>> case 4: ...
>> case 5: ...
>> case 6: ...
>> case 7: ...
>> }
>>
>> I'll grant that this sort of situation doesn't arise all that often,
>> and I'll grant that there are other ways to write the logic (there's
>> usually more than one way to do something in C), but I think you're
>> going overboard in trying to legislate the pattern out of existence.
>
> If bool were a strictly logical type, on which no arithmetic could be
> performed, that pattern would still be allowed, the syntax would just be
> slightly more complicated:
>
> (expensive()?4:0) + (complicated()?2:0) + (long_winded()?1:0)
"I'll grant that there are other ways to write the logic," as
a person I deeply respect once wrote.
Here's another example where arithmetic on bool is handy:
const int days_in_month[2][12] = {
{ 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 },
{ 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }
};
bool is_leap_year = ...;
int month = ...;
int days = days_in_month[is_leap_year][month - 1];
"One (int) cast and all's well," but don't forget the skeptical
glance one usually casts upon casts...
--
Eric Sosman
esosman@ieee-dot-org.invalid
[toc] | [prev] | [next] | [standalone]
| From | James Kuyper <jameskuyper@verizon.net> |
|---|---|
| Date | 2012-04-26 21:58 -0400 |
| Message-ID | <jncuh1$ls$1@dont-email.me> |
| In reply to | #19989 |
On 04/26/2012 09:29 PM, Eric Sosman wrote:
...
> "I'll grant that there are other ways to write the logic," as
> a person I deeply respect once wrote.
>
> Here's another example where arithmetic on bool is handy:
>
> const int days_in_month[2][12] = {
> { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 },
> { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }
> };
> bool is_leap_year = ...;
> int month = ...;
> int days = days_in_month[is_leap_year][month - 1];
>
> "One (int) cast and all's well," but don't forget the skeptical
> glance one usually casts upon casts...
In a hypothetical C-like language where bools were truly a separate
type, a cast to int would not be allowed. Instead, use
(isleap_year ? 1 : 0).
--
James Kuyper
[toc] | [prev] | [next] | [standalone]
| From | Eric Sosman <esosman@ieee-dot-org.invalid> |
|---|---|
| Date | 2012-04-26 22:32 -0400 |
| Message-ID | <jnd0fk$8vk$1@dont-email.me> |
| In reply to | #19990 |
On 4/26/2012 9:58 PM, James Kuyper wrote:
> On 04/26/2012 09:29 PM, Eric Sosman wrote:
> ...
>> "I'll grant that there are other ways to write the logic," as
>> a person I deeply respect once wrote.
>>
>> Here's another example where arithmetic on bool is handy:
>>
>> const int days_in_month[2][12] = {
>> { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 },
>> { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }
>> };
>> bool is_leap_year = ...;
>> int month = ...;
>> int days = days_in_month[is_leap_year][month - 1];
>>
>> "One (int) cast and all's well," but don't forget the skeptical
>> glance one usually casts upon casts...
>
> In a hypothetical C-like language where bools were truly a separate
> type, a cast to int would not be allowed. Instead, use
> (isleap_year ? 1 : 0).
"I'll grant ..." (Is there an echo in here?)
The question that burns in my feeble brain is: "Why?" What is
the benefit that a "No arithmetic on booleans" rule would bring?
In what way would the hypothetical C-like language be superior to
C-where-ints-work-just-fine-thanks? I'm not inclined to accept
unsupported assertions like "Cleanliness is next to Godliness,"
but would attend to concrete, measurable, or estimatable advantages,
or to credible first-person anecdotes.
So far, the only thing I've heard is the O.P.'s complaint
that the compiler allowed him to get himself in trouble by making
code changes without first understanding the code he was changing.
Well, golly.
If you're looking for a language with seat belts, training
wheels, airbags, and padded walls, C shouldn't be your first
choice, and restrictions on arithmetic wouldn't change matters.
--
Eric Sosman
esosman@ieee-dot-org.invalid
[toc] | [prev] | [next] | [standalone]
| From | James Kuyper <jameskuyper@verizon.net> |
|---|---|
| Date | 2012-04-27 06:31 -0400 |
| Message-ID | <jndsiu$60v$1@dont-email.me> |
| In reply to | #19991 |
On 04/26/2012 10:32 PM, Eric Sosman wrote: > On 4/26/2012 9:58 PM, James Kuyper wrote: ... >> In a hypothetical C-like language where bools were truly a separate >> type, a cast to int would not be allowed. Instead, use >> (isleap_year ? 1 : 0). > > "I'll grant ..." (Is there an echo in here?) > > The question that burns in my feeble brain is: "Why?" What is > the benefit that a "No arithmetic on booleans" rule would bring? It makes syntax errors out of constructs that are conceptually meaningless, forcing the use of alternative constructs that say more precisely what is actually going on. As such, it makes it easier to detect erroneous constructs. ... > If you're looking for a language with seat belts, training > wheels, airbags, and padded walls, C shouldn't be your first > choice, and restrictions on arithmetic wouldn't change matters. A C-like language with few more barriers between conceptually distinct things like numbers, characters, and bools than C has, would make it slightly easier to avoid writing nonsense. Those barriers wouldn't cause the loss of any truly valuable characteristic of C. -- James Kuyper
[toc] | [prev] | [next] | [standalone]
| From | Lanarcam <lanarcam1@yahoo.fr> |
|---|---|
| Date | 2012-04-27 19:26 +0200 |
| Message-ID | <4f9ad6b4$0$21924$426a74cc@news.free.fr> |
| In reply to | #19996 |
Le 27/04/2012 12:31, James Kuyper a écrit : > On 04/26/2012 10:32 PM, Eric Sosman wrote: >> On 4/26/2012 9:58 PM, James Kuyper wrote: > ... >>> In a hypothetical C-like language where bools were truly a separate >>> type, a cast to int would not be allowed. Instead, use >>> (isleap_year ? 1 : 0). >> >> "I'll grant ..." (Is there an echo in here?) >> >> The question that burns in my feeble brain is: "Why?" What is >> the benefit that a "No arithmetic on booleans" rule would bring? > > It makes syntax errors out of constructs that are conceptually > meaningless, forcing the use of alternative constructs that say more > precisely what is actually going on. As such, it makes it easier to > detect erroneous constructs. > > ... >> If you're looking for a language with seat belts, training >> wheels, airbags, and padded walls, C shouldn't be your first >> choice, and restrictions on arithmetic wouldn't change matters. > > A C-like language with few more barriers between conceptually distinct > things like numbers, characters, and bools than C has, would make it > slightly easier to avoid writing nonsense. Those barriers wouldn't cause > the loss of any truly valuable characteristic of C. I think you mean ADA.
[toc] | [prev] | [next] | [standalone]
| From | Keith Thompson <kst-u@mib.org> |
|---|---|
| Date | 2012-04-27 11:28 -0700 |
| Message-ID | <lnehr9vxjt.fsf@nuthaus.mib.org> |
| In reply to | #20001 |
Lanarcam <lanarcam1@yahoo.fr> writes:
> Le 27/04/2012 12:31, James Kuyper a écrit :
>> On 04/26/2012 10:32 PM, Eric Sosman wrote:
[...]
>>> If you're looking for a language with seat belts, training
>>> wheels, airbags, and padded walls, C shouldn't be your first
>>> choice, and restrictions on arithmetic wouldn't change matters.
>>
>> A C-like language with few more barriers between conceptually distinct
>> things like numbers, characters, and bools than C has, would make it
>> slightly easier to avoid writing nonsense. Those barriers wouldn't cause
>> the loss of any truly valuable characteristic of C.
>
> I think you mean ADA.
I think *you* mean Ada (the name is not an acronym).
But one could have a C-like language with fewer implicit conversions
without going as far as Ada, which doesn't even have implicit
conversions between otherwise identical integer types.
I can imagine a C-like language with, say, the following features:
- C-like implicit conversions among all numeric types, signed, unsigned,
and floating-point -- or maybe only allow implicit conversions within
each of the three kinds of numeric types (yes, I'm ignoring _Complex
for now)
- bool is treated as a scalar but non-numeric type
- Each enumerated type is treated as a scalar but non-numeric type
(bool could be a special-case enumerated type, with false and true as
enumerated constants)
- No implicit conversions between numeric and non-numeric types (but
casts work as in C)
- 0 is not a null pointer constant; instead, there's a keyword (say,
"nil") that is the language's *only* null pointer constant
- Relational and equality operators yield bool results
- Contexts that require conditions (if, for, while, do-while, !, &&, ||,
?:, and whatever else I've forgotten) require a bool expression
Some implications:
- The NULL macro is unnecessary, and is replaced by the nil keyword.
- You'd have to write "if (num != 0)" rather than "if (num)".
- You'd have to write "if (ptr != nil)" rather than "if (ptr)".
- There are undoubtedly more implications that would have to be worked
out.
This hypothetical language would be closer to Ada than C is, but
it's still much closer to C than it is to Ada. Think of a scale
with C at 0, Ada at 1, and this language at perhaps 0.05 or 0.1.
I do not suggest for a moment that C itself should be changed like this.
It would break almost all existing C code, and that's clearly unacceptable.
But personally, I think I'd like it a little better than I like C. (And
if I ever actually invented such a thing, I'd probably also clean up the
treatment of arrays and pointers.)
--
Keith Thompson (The_Other_Keith) kst-u@mib.org <http://www.ghoti.net/~kst>
Will write code for food.
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
[toc] | [prev] | [next] | [standalone]
| From | Lanarcam <lanarcam1@yahoo.fr> |
|---|---|
| Date | 2012-04-27 20:51 +0200 |
| Message-ID | <4f9aead3$0$20164$426a74cc@news.free.fr> |
| In reply to | #20004 |
Le 27/04/2012 20:28, Keith Thompson a écrit : > Lanarcam<lanarcam1@yahoo.fr> writes: >> Le 27/04/2012 12:31, James Kuyper a écrit : >>> On 04/26/2012 10:32 PM, Eric Sosman wrote: > [...] >>>> If you're looking for a language with seat belts, training >>>> wheels, airbags, and padded walls, C shouldn't be your first >>>> choice, and restrictions on arithmetic wouldn't change matters. >>> >>> A C-like language with few more barriers between conceptually distinct >>> things like numbers, characters, and bools than C has, would make it >>> slightly easier to avoid writing nonsense. Those barriers wouldn't cause >>> the loss of any truly valuable characteristic of C. >> >> I think you mean ADA. > > I think *you* mean Ada (the name is not an acronym). > > But one could have a C-like language with fewer implicit conversions > without going as far as Ada, which doesn't even have implicit > conversions between otherwise identical integer types. > > I can imagine a C-like language with, say, the following features: > > - C-like implicit conversions among all numeric types, signed, unsigned, > and floating-point -- or maybe only allow implicit conversions within > each of the three kinds of numeric types (yes, I'm ignoring _Complex > for now) > > - bool is treated as a scalar but non-numeric type > > - Each enumerated type is treated as a scalar but non-numeric type > (bool could be a special-case enumerated type, with false and true as > enumerated constants) > > - No implicit conversions between numeric and non-numeric types (but > casts work as in C) > > - 0 is not a null pointer constant; instead, there's a keyword (say, > "nil") that is the language's *only* null pointer constant > > - Relational and equality operators yield bool results > > - Contexts that require conditions (if, for, while, do-while, !,&&, ||, > ?:, and whatever else I've forgotten) require a bool expression > > Some implications: > > - The NULL macro is unnecessary, and is replaced by the nil keyword. > > - You'd have to write "if (num != 0)" rather than "if (num)". > > - You'd have to write "if (ptr != nil)" rather than "if (ptr)". > > - There are undoubtedly more implications that would have to be worked > out. > > This hypothetical language would be closer to Ada than C is, but > it's still much closer to C than it is to Ada. Think of a scale > with C at 0, Ada at 1, and this language at perhaps 0.05 or 0.1. > > I do not suggest for a moment that C itself should be changed like this. > It would break almost all existing C code, and that's clearly unacceptable. > > But personally, I think I'd like it a little better than I like C. (And > if I ever actually invented such a thing, I'd probably also clean up the > treatment of arrays and pointers.) > I agree, one could think also of C + MISRA, the coding standard for safety devices in automotive with many restrictions that try to avoid the unsafety of C.
[toc] | [prev] | [next] | [standalone]
| From | ImpalerCore <jadill33@gmail.com> |
|---|---|
| Date | 2012-04-27 12:17 -0700 |
| Message-ID | <f6e60b1e-c840-4f43-a85e-3ac1672132a7@a5g2000vbl.googlegroups.com> |
| In reply to | #20004 |
On Apr 27, 2:28 pm, Keith Thompson <ks...@mib.org> wrote: > Lanarcam <lanarc...@yahoo.fr> writes: > > Le 27/04/2012 12:31, James Kuyper a écrit : > >> On 04/26/2012 10:32 PM, Eric Sosman wrote: > [...] > >>> If you're looking for a language with seat belts, training > >>> wheels, airbags, and padded walls, C shouldn't be your first > >>> choice, and restrictions on arithmetic wouldn't change matters. > > >> A C-like language with few more barriers between conceptually distinct > >> things like numbers, characters, and bools than C has, would make it > >> slightly easier to avoid writing nonsense. Those barriers wouldn't cause > >> the loss of any truly valuable characteristic of C. > > > I think you mean ADA. > > I think *you* mean Ada (the name is not an acronym). > > But one could have a C-like language with fewer implicit conversions > without going as far as Ada, which doesn't even have implicit > conversions between otherwise identical integer types. > > I can imagine a C-like language with, say, the following features: > > - C-like implicit conversions among all numeric types, signed, unsigned, > and floating-point -- or maybe only allow implicit conversions within > each of the three kinds of numeric types (yes, I'm ignoring _Complex > for now) > > - bool is treated as a scalar but non-numeric type > > - Each enumerated type is treated as a scalar but non-numeric type > (bool could be a special-case enumerated type, with false and true as > enumerated constants) > > - No implicit conversions between numeric and non-numeric types (but > casts work as in C) > > - 0 is not a null pointer constant; instead, there's a keyword (say, > "nil") that is the language's *only* null pointer constant > > - Relational and equality operators yield bool results > > - Contexts that require conditions (if, for, while, do-while, !, &&, ||, > ?:, and whatever else I've forgotten) require a bool expression > > Some implications: > > - The NULL macro is unnecessary, and is replaced by the nil keyword. > > - You'd have to write "if (num != 0)" rather than "if (num)". > > - You'd have to write "if (ptr != nil)" rather than "if (ptr)". > > - There are undoubtedly more implications that would have to be worked > out. > > This hypothetical language would be closer to Ada than C is, but > it's still much closer to C than it is to Ada. Think of a scale > with C at 0, Ada at 1, and this language at perhaps 0.05 or 0.1. > > I do not suggest for a moment that C itself should be changed like this. > It would break almost all existing C code, and that's clearly unacceptable. True, but I'd be in favor of a -pedantic-thompson flag that warns about many of these rules. > But personally, I think I'd like it a little better than I like C. (And > if I ever actually invented such a thing, I'd probably also clean up the > treatment of arrays and pointers.) Best regards, John D.
[toc] | [prev] | [next] | [standalone]
| From | Jens Gustedt <jens.gustedt@loria.fr> |
|---|---|
| Date | 2012-04-28 09:17 +0200 |
| Message-ID | <4F9B997F.6060901@loria.fr> |
| In reply to | #20004 |
Am 04/27/2012 08:28 PM, schrieb Keith Thompson: > - bool is treated as a scalar but non-numeric type > - Each enumerated type is treated as a scalar but non-numeric type > (bool could be a special-case enumerated type, with false and true as > enumerated constants) > > - No implicit conversions between numeric and non-numeric types (but > casts work as in C) I don't see any good reason to forbid conversions *to* bool. While I can image the confusion that was at the origin of this thread of using bool in arithmetic, the converse rules how to interpret numeric and pointer types in a boolean context are nice and clean. Also I don't think that the current conversion rules for integer types are ideal, since they are inconsistent between the preprocessor phase and the rest of the compilation. Why not just have all integer arithmetic happen in intmax_t or uintmax_t (and let the optimizer do a bit of work if it can be proven that smaller types can be proven to be sufficient) ? > - 0 is not a null pointer constant; instead, there's a keyword (say, > "nil") that is the language's *only* null pointer constant I don't see the value of this either. The problem in C is not with 0 (and other values) as a null pointer constant but with the underspecification of NULL. Having a catch-all initializer for all data types is quite convenient, I would miss that. > - Relational and equality operators yield bool results > > - Contexts that require conditions (if, for, while, do-while, !, &&, ||, > ?:, and whatever else I've forgotten) require a bool expression > > Some implications: > > - The NULL macro is unnecessary, and is replaced by the nil keyword. this would be a good one, why not call it nullptr to keep it in sync with C++ ? And in current C an identifier that is forced to the value (void*)0 would perfectly play that role. > - You'd have to write "if (num != 0)" rather than "if (num)". > > - You'd have to write "if (ptr != nil)" rather than "if (ptr)". I personally wouldn't like that one > - There are undoubtedly more implications that would have to be worked > out. I'd add another thing to that list: unprototyped functions. They are particularly bad because of the lack of pointer conversion for their arguments. One could enforce an implicit conversion rule to void* for them, with the consequence that passing an `int const*` to an unspecific parameter wouldn't compile at all, or just forbid unprototyped functions completely. I would prefer the later, I think, with the consequence of also banning va_arg functions. Jens
[toc] | [prev] | [next] | [standalone]
| From | Keith Thompson <kst-u@mib.org> |
|---|---|
| Date | 2012-04-28 13:26 -0700 |
| Message-ID | <ln62cjwqkl.fsf@nuthaus.mib.org> |
| In reply to | #20021 |
Jens Gustedt <jens.gustedt@loria.fr> writes:
> Am 04/27/2012 08:28 PM, schrieb Keith Thompson:
>> - bool is treated as a scalar but non-numeric type
>> - Each enumerated type is treated as a scalar but non-numeric type
>> (bool could be a special-case enumerated type, with false and true as
>> enumerated constants)
>>
>> - No implicit conversions between numeric and non-numeric types (but
>> casts work as in C)
>
> I don't see any good reason to forbid conversions *to* bool.
Remember that the whole point of this hypothetical language is that it's
reasonably similar to C, but with no concern for compatibility, and
removing features that *I personally* dislike. It's not so much a
proposed replacement for C as it is what C might have been like if I had
designed it myself, knowing what I know now.
Which makes this of questionable topicality, but perhaps it can provide
some insight into the design of C as it actually is.
By not having implicit conversions to bool, you don't have to define the
semantics of such conversions. I find the convention that zero is false
and anything else is true to be arbitrary and unnecessary. (I learned
Pascal before I learned C, and I spent a number of years programming in
Ada. Neither of them has such a convention, and both, IMHO, demonstrate
that a language can get along just fine without it.)
bool (or Boolean, or ...) is a type with values false and true.
Comparisons yield bool results. Conditions must be of type bool. It
requires a little extra typing now and then, but I personally find such
a design cleaner than C's handling of conditions (with type _Bool tacked
on years after the language was originally designed).
> While I can image the confusion that was at the origin of this thread
> of using bool in arithmetic, the converse rules how to interpret
> numeric and pointer types in a boolean context are nice and clean.
Ok, but I find "if (num != 0)" and "if (ptr != NULL)" much clearer than
"if (num)" and "if (ptr)", respectively. For one thing, the more
verbose versions make it more obvious what kind of value is being
tested, if it has a name that's not as obvious as "num" or "ptr".
> Also I don't think that the current conversion rules for integer types
> are ideal, since they are inconsistent between the preprocessor phase
> and the rest of the compilation. Why not just have all integer
> arithmetic happen in intmax_t or uintmax_t (and let the optimizer do a
> bit of work if it can be proven that smaller types can be proven to be
> sufficient) ?
Interesting idea, but you could get some performance glitches as small
changes in an expression alter the optimizer's ability to use a smaller
type. Imagine a small tweak to an expression affecting the speed of an
inner loop by a factor of 10 or so. intmax_t and uintmax_t can be very
inefficient, and in an expression as simple as "x + y" it can be
impossible for the optimizer to prove that it won't overflow.
>> - 0 is not a null pointer constant; instead, there's a keyword (say,
>> "nil") that is the language's *only* null pointer constant
>
> I don't see the value of this either. The problem in C is not with 0
> (and other values) as a null pointer constant but with the
> underspecification of NULL.
The problem is that I dislike the use of an int constant 0 to denote a
null pointer value. It contributes to the confusion about the
relationship between integers and pointers. The comp.lang.c FAQ,
<http://c-faq.com/>, has an entire section on null pointers; in my
hypothetical language, that section could probably be reduced to one
question, if that. (And section 9, "Boolean Expressions and Variables",
would probably also be a lot smaller.)
> Having a catch-all initializer for all data types is quite convenient,
> I would miss that.
I agree; being able to write:
some_type obj = { 0 };
and have it work for *any* type is very nice. I can think of ways to
get similar semantics in my hypothetical language, but this is getting
too long already.
>> - Relational and equality operators yield bool results
>>
>> - Contexts that require conditions (if, for, while, do-while, !, &&, ||,
>> ?:, and whatever else I've forgotten) require a bool expression
>>
>> Some implications:
>>
>> - The NULL macro is unnecessary, and is replaced by the nil keyword.
>
> this would be a good one, why not call it nullptr to keep it in sync
> with C++ ? And in current C an identifier that is forced to the value
> (void*)0 would perfectly play that role.
My hypothetical language explicitly rejects compatibility with C; why
should I care about staying in sync with C++? 8-)}
I think C++ used the name "nullptr" to avoid conflicting with
identifiers used in existing code. I like the name "nil" (and there's
precedent for it or for "null", in other languages).
>> - You'd have to write "if (num != 0)" rather than "if (num)".
>>
>> - You'd have to write "if (ptr != nil)" rather than "if (ptr)".
>
> I personally wouldn't like that one
Fair enough. I do.
>> - There are undoubtedly more implications that would have to be worked
>> out.
>
> I'd add another thing to that list: unprototyped functions. They are
> particularly bad because of the lack of pointer conversion for their
> arguments.
>
> One could enforce an implicit conversion rule to void* for them, with
> the consequence that passing an `int const*` to an unspecific
> parameter wouldn't compile at all, or just forbid unprototyped
> functions completely. I would prefer the later, I think, with the
> consequence of also banning va_arg functions.
I hadn't thought about that particular feature, but yes, old-style
function declarations and definitions would definitely be on the
chopping block. They've been "obsolescent" in C since the 1989
ANSI standard.
I wouldn't ban variadic functions without having a good replacement
for them. printf is error-prone, but very powerful. (C++'s use of
an overloaded "<<" operator is nice, but the fact that specifying
a numeric output format changes the state of the stream is *ugly*.
(But I digress.))
And for those who dislike my hypothetical language, I don't think
there's much chance that I'll ever get around to specifying it, let
alone implementing it.
--
Keith Thompson (The_Other_Keith) kst-u@mib.org <http://www.ghoti.net/~kst>
Will write code for food.
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
[toc] | [prev] | [next] | [standalone]
| From | Willem <willem@toad.stack.nl> |
|---|---|
| Date | 2012-04-27 18:11 +0000 |
| Message-ID | <slrnjploaa.bth.willem@toad.stack.nl> |
| In reply to | #19996 |
James Kuyper wrote:
) On 04/26/2012 10:32 PM, Eric Sosman wrote:
)> The question that burns in my feeble brain is: "Why?" What is
)> the benefit that a "No arithmetic on booleans" rule would bring?
)
) It makes syntax errors out of constructs that are conceptually
) meaningless, forcing the use of alternative constructs that say more
) precisely what is actually going on. As such, it makes it easier to
) detect erroneous constructs.
It also makes syntax errors out of constructs that are perfectly
meaningful, forcing the use of needless extra boilerplate code
that only serves to muddle what is actually going on.
The boundary between the two is purely a matter of taste.
SaSW, Willem
--
Disclaimer: I am in no way responsible for any of the statements
made in the above text. For all I know I might be
drugged or something..
No I'm not paranoid. You all think I'm paranoid, don't you !
#EOT
[toc] | [prev] | [next] | [standalone]
| From | ImpalerCore <jadill33@gmail.com> |
|---|---|
| Date | 2012-04-27 12:05 -0700 |
| Message-ID | <45aaf68b-8f97-413c-bd0d-05afb1752adb@a5g2000vbl.googlegroups.com> |
| In reply to | #20002 |
On Apr 27, 2:11 pm, Willem <wil...@toad.stack.nl> wrote:
> James Kuyper wrote:
>
> ) On 04/26/2012 10:32 PM, Eric Sosman wrote:
> )> The question that burns in my feeble brain is: "Why?" What is
> )> the benefit that a "No arithmetic on booleans" rule would bring?
> )
> ) It makes syntax errors out of constructs that are conceptually
> ) meaningless, forcing the use of alternative constructs that say more
> ) precisely what is actually going on. As such, it makes it easier to
> ) detect erroneous constructs.
>
> It also makes syntax errors out of constructs that are perfectly
> meaningful, forcing the use of needless extra boilerplate code
> that only serves to muddle what is actually going on.
>
> The boundary between the two is purely a matter of taste.
Alright, let's put a sample out there. Do you believe that it would
be beneficial to go to the trouble of defining 'streq' just to
parameterize string equality in terms of a bool?
bool streq( const char* s1, const char* s2 )
{ return strcmp( s1, s2 ) == 0; }
Would you consider it a candidate for discussion of including it in
some future C standard, or consider it a waste of committee members
time? The example is completely trivial to implement, but I think it
illustrates one's perception of their value of abstraction vs
convenience.
For my purposes, the main benefit is that this extra conceptual
stratification allows one to separate comparison (-,0,+) functions
from search (true,false) functions for distinguishing operations in a
container interface.
struct c_list* c_list_search( struct c_list* list,
const void* property,
bool (*pred_fn)( const void*, const
void* ) );
I can accomplish the same thing with the canonical 'int (*cmp_fn)
( const void*, const void* )'. I just see more conceptual value in
defining search to use the 'pred_fn' version over the 'cmp_fn' version
(hence the motivation for defining my own 'c_streq' in the first
place).
Best regards,
John D.
[toc] | [prev] | [next] | [standalone]
| From | James Kuyper <jameskuyper@verizon.net> |
|---|---|
| Date | 2012-04-27 15:32 -0400 |
| Message-ID | <4F9AF44F.3040307@verizon.net> |
| In reply to | #20002 |
On 04/27/2012 02:11 PM, Willem wrote: > James Kuyper wrote: > ) On 04/26/2012 10:32 PM, Eric Sosman wrote: > )> The question that burns in my feeble brain is: "Why?" What is > )> the benefit that a "No arithmetic on booleans" rule would bring? > ) > ) It makes syntax errors out of constructs that are conceptually > ) meaningless, forcing the use of alternative constructs that say more > ) precisely what is actually going on. As such, it makes it easier to > ) detect erroneous constructs. > > It also makes syntax errors out of constructs that are perfectly > meaningful, forcing the use of needless extra boilerplate code > that only serves to muddle what is actually going on. I deny the fundamental meaningfullness of any code that treats a logical value as if it were numeric. What does true*3+false mean? It has a specific numeric meaning, one that almost any C programmer would know - but only because C arbitrarily gave it that meaning, not because it has any inherent meaning. It's intrinsically meaningless to multiply a truth value by 3.
[toc] | [prev] | [next] | [standalone]
| From | Willem <willem@toad.stack.nl> |
|---|---|
| Date | 2012-04-27 20:16 +0000 |
| Message-ID | <slrnjplvlo.v3t.willem@toad.stack.nl> |
| In reply to | #20008 |
James Kuyper wrote:
) On 04/27/2012 02:11 PM, Willem wrote:
)> James Kuyper wrote:
)> ) On 04/26/2012 10:32 PM, Eric Sosman wrote:
)> )> The question that burns in my feeble brain is: "Why?" What is
)> )> the benefit that a "No arithmetic on booleans" rule would bring?
)> )
)> ) It makes syntax errors out of constructs that are conceptually
)> ) meaningless, forcing the use of alternative constructs that say more
)> ) precisely what is actually going on. As such, it makes it easier to
)> ) detect erroneous constructs.
)>
)> It also makes syntax errors out of constructs that are perfectly
)> meaningful, forcing the use of needless extra boilerplate code
)> that only serves to muddle what is actually going on.
)
) I deny the fundamental meaningfullness of any code that treats a logical
) value as if it were numeric. What does true*3+false mean? It has a
) specific numeric meaning, one that almost any C programmer would know -
) but only because C arbitrarily gave it that meaning, not because it has
) any inherent meaning. It's intrinsically meaningless to multiply a truth
) value by 3.
My apologies, I had misunderstood the statement as: "No using arbitratry
expressions as booleans", but for the other way round, calculating with
booleans, I almost(*) completely agree with you.
*) Bit-shifting is an exception, IMO.
SaSW, Willem
--
Disclaimer: I am in no way responsible for any of the statements
made in the above text. For all I know I might be
drugged or something..
No I'm not paranoid. You all think I'm paranoid, don't you !
#EOT
[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