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


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

redeclaration of enumerators?

Started byThiago Adams <thiago.adams@gmail.com>
First post2021-09-27 10:39 -0700
Last post2021-09-29 03:40 +0000
Articles 9 on this page of 49 — 13 participants

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


Contents

  redeclaration of enumerators? Thiago Adams <thiago.adams@gmail.com> - 2021-09-27 10:39 -0700
    Re: redeclaration of enumerators? John Bode <jfbode1029@gmail.com> - 2021-09-28 16:21 -0500
      Re: redeclaration of enumerators? Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2021-09-28 14:57 -0700
        Re: redeclaration of enumerators? Thiago Adams <thiago.adams@gmail.com> - 2021-09-28 15:23 -0700
          Re: redeclaration of enumerators? David Brown <david.brown@hesbynett.no> - 2021-09-29 15:23 +0200
          Re: redeclaration of enumerators? Mark Bluemel <mark.bluemel@gmail.com> - 2021-09-30 01:15 -0700
        Re: redeclaration of enumerators? Bart <bc@freeuk.com> - 2021-09-28 23:31 +0100
          Re: redeclaration of enumerators? David Brown <david.brown@hesbynett.no> - 2021-09-29 15:36 +0200
            Re: redeclaration of enumerators? Bart <bc@freeuk.com> - 2021-09-29 15:03 +0100
              Re: redeclaration of enumerators? David Brown <david.brown@hesbynett.no> - 2021-09-29 16:46 +0200
                Re: redeclaration of enumerators? Bart <bc@freeuk.com> - 2021-09-29 16:08 +0100
                  Re: redeclaration of enumerators? David Brown <david.brown@hesbynett.no> - 2021-09-29 20:14 +0200
                    Re: redeclaration of enumerators? Thiago Adams <thiago.adams@gmail.com> - 2021-09-29 13:37 -0700
                    Re: redeclaration of enumerators? Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2021-09-29 18:25 -0700
                      Re: redeclaration of enumerators? David Brown <david.brown@hesbynett.no> - 2021-09-30 12:45 +0200
                        Re: redeclaration of enumerators? Malcolm McLean <malcolm.arthur.mclean@gmail.com> - 2021-09-30 07:36 -0700
                          Re: redeclaration of enumerators? David Brown <david.brown@hesbynett.no> - 2021-10-01 09:20 +0200
                            Re: redeclaration of enumerators? Bart <bc@freeuk.com> - 2021-10-01 11:24 +0100
                              Re: redeclaration of enumerators? Malcolm McLean <malcolm.arthur.mclean@gmail.com> - 2021-10-01 04:49 -0700
                                Re: redeclaration of enumerators? Bart <bc@freeuk.com> - 2021-10-01 13:06 +0100
                                  Re: redeclaration of enumerators? Tony Oliver <guinness.tony@gmail.com> - 2021-10-01 05:24 -0700
                                    Re: redeclaration of enumerators? Bart <bc@freeuk.com> - 2021-10-01 13:32 +0100
                                  Re: redeclaration of enumerators? Malcolm McLean <malcolm.arthur.mclean@gmail.com> - 2021-10-01 05:32 -0700
                                    Re: redeclaration of enumerators? Bart <bc@freeuk.com> - 2021-10-01 13:43 +0100
                                      Re: redeclaration of enumerators? Mark Bluemel <mark.bluemel@gmail.com> - 2021-10-01 06:13 -0700
                                      Re: redeclaration of enumerators? Malcolm McLean <malcolm.arthur.mclean@gmail.com> - 2021-10-01 06:29 -0700
                                    Re: redeclaration of enumerators? Ben Bacarisse <ben.usenet@bsb.me.uk> - 2021-10-01 15:30 +0100
                                      Re: redeclaration of enumerators? Malcolm McLean <malcolm.arthur.mclean@gmail.com> - 2021-10-01 08:28 -0700
                                        Re: redeclaration of enumerators? Ben Bacarisse <ben.usenet@bsb.me.uk> - 2021-10-01 17:08 +0100
                                          Re: redeclaration of enumerators? Malcolm McLean <malcolm.arthur.mclean@gmail.com> - 2021-10-01 15:12 -0700
                                  Re: redeclaration of enumerators? David Brown <david.brown@hesbynett.no> - 2021-10-01 15:37 +0200
                                    Re: redeclaration of enumerators? Bart <bc@freeuk.com> - 2021-10-01 15:30 +0100
                                      Re: redeclaration of enumerators? David Brown <david.brown@hesbynett.no> - 2021-10-01 19:12 +0200
                                        Re: redeclaration of enumerators? Bart <bc@freeuk.com> - 2021-10-01 19:06 +0100
                              Re: redeclaration of enumerators? David Brown <david.brown@hesbynett.no> - 2021-10-01 15:32 +0200
                                Re: redeclaration of enumerators? Bart <bc@freeuk.com> - 2021-10-01 15:38 +0100
                                  Re: redeclaration of enumerators? Bart <bc@freeuk.com> - 2021-10-01 17:40 +0100
                              Re: redeclaration of enumerators? Bart <bc@freeuk.com> - 2021-10-02 12:16 +0100
                                Re: redeclaration of enumerators? David Brown <david.brown@hesbynett.no> - 2021-10-02 15:34 +0200
                                  Re: redeclaration of enumerators? Bart <bc@freeuk.com> - 2021-10-02 15:16 +0100
                            Re: redeclaration of enumerators? Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2021-10-01 13:58 -0700
                              Re: redeclaration of enumerators? Richard Damon <Richard@Damon-Family.org> - 2021-10-01 17:21 -0400
                              Re: redeclaration of enumerators? Malcolm McLean <malcolm.arthur.mclean@gmail.com> - 2021-10-01 14:56 -0700
                              Re: redeclaration of enumerators? David Brown <david.brown@hesbynett.no> - 2021-10-02 12:21 +0200
                        Re: redeclaration of enumerators? scott@slp53.sl.home (Scott Lurndal) - 2021-09-30 14:47 +0000
                          Re: redeclaration of enumerators? Malcolm McLean <malcolm.arthur.mclean@gmail.com> - 2021-09-30 10:10 -0700
                          Re: redeclaration of enumerators? David Brown <david.brown@hesbynett.no> - 2021-10-01 09:24 +0200
              Re: redeclaration of enumerators? Andrey Tarasevich <andreytarasevich@hotmail.com> - 2021-09-29 12:43 -0700
      Re: redeclaration of enumerators? Branimir Maksimovic <branimir.maksimovic@gmail.com> - 2021-09-29 03:40 +0000

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


#162918

FromKeith Thompson <Keith.S.Thompson+u@gmail.com>
Date2021-10-01 13:58 -0700
Message-ID<8735pkihrn.fsf@nosuchdomain.example.com>
In reply to#162887
David Brown <david.brown@hesbynett.no> writes:
> On 30/09/2021 16:36, Malcolm McLean wrote:
>> On Thursday, 30 September 2021 at 11:45:50 UTC+1, David Brown wrote:
>>>
>>> But I think that in most cases, it is not at all helpful to think about 
>>> the underlying integer values. You get cleaner, safer, more portable 
>>> code if you treat the enumeration constants as being abstract symbols 
>>> that are members of the particular type without any other semantics or 
>>> meaning.
>>>
>> I agree, but there are some snags. One is if you wish to print out
>> the enum for debug purposes. It's easy enough to write printf("light
>> %d\n", (int) lightenumval); If you have to set up an enum to string
>> function then it's a bit clearer, but it's a huge hassle for debug.
>> The other snag is that often you want to use the enum to index into a table
>> of some sort. Again, you can set up a system by writing a switch, but that's
>> likely slower and more code. 
>
> These are not "snags" - they are cases where the underlying integer
> value of the enumeration constants is sometimes helpful due to the
> limitations of the language.  Eventually, C++ will get some decent
> compile-time reflection capabilities that will allow you to generate
> strings from enumeration constants simply and easily, without repetition
> in the code (and without complicated X-macros).

Even for C++ scoped enumerations, each enumerator has a well defined
numeric value that can be specified in the declaration and accessed by
casting to an integer type.  This is part of the language-defined
semantics of the feature, not something that the language incorrectly
fails to hide.

I've personally found it annoying that a scoped enum can't be used as an
array index.  (Ada's enumeration types are distinct types, more strongly
typed than C++'s scoped enums, and they can be used as array
indices.  Of course neither C nor C++ is Ada, nor should they be.)

It's difficult to extend a weakly typed feature like C's enum and make
it reasonably type-safe without breaking things.  If C were to add a
more strongly typed enumeration feature, it would probably make sense to
adopt something very similar to what C++ has already done.

> In the meantime, C99, and C++ with gcc extensions (unfortunately not
> standard), let you write:
>
>
> typedef enum Colours { red, green, blue } Colours;
>
> extern const char * const colour_names[];
> const char * const colour_names[] = {
>     [red] = "red",
>     [green] = "green",
>     [blue] = "blue",
> };
>
> This does not use or rely on underlying integer values in any way -
> there is no need even to have the same order in the array definition as
> in the enumeration.
>
> For convenience (and for standard C++) you might define such an array
> without designated initialisers, but you are still trying to view the
> enumeration elements as abstract symbols, not as merely names for
> integer constants.

If you're going to be doing this a lot, it probably makes sense to
generate the table automatically.

-- 
Keith Thompson (The_Other_Keith) Keith.S.Thompson+u@gmail.com
Working, but not speaking, for Philips
void Void(void) { Void(); } /* The recursive call of the void */

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


#162920

FromRichard Damon <Richard@Damon-Family.org>
Date2021-10-01 17:21 -0400
Message-ID<TZK5J.50388$3p3.15374@fx16.iad>
In reply to#162918
On 10/1/21 4:58 PM, Keith Thompson wrote:
> David Brown <david.brown@hesbynett.no> writes:
>> On 30/09/2021 16:36, Malcolm McLean wrote:
>>> On Thursday, 30 September 2021 at 11:45:50 UTC+1, David Brown wrote:
>>>>
>>>> But I think that in most cases, it is not at all helpful to think about 
>>>> the underlying integer values. You get cleaner, safer, more portable 
>>>> code if you treat the enumeration constants as being abstract symbols 
>>>> that are members of the particular type without any other semantics or 
>>>> meaning.
>>>>
>>> I agree, but there are some snags. One is if you wish to print out
>>> the enum for debug purposes. It's easy enough to write printf("light
>>> %d\n", (int) lightenumval); If you have to set up an enum to string
>>> function then it's a bit clearer, but it's a huge hassle for debug.
>>> The other snag is that often you want to use the enum to index into a table
>>> of some sort. Again, you can set up a system by writing a switch, but that's
>>> likely slower and more code. 
>>
>> These are not "snags" - they are cases where the underlying integer
>> value of the enumeration constants is sometimes helpful due to the
>> limitations of the language.  Eventually, C++ will get some decent
>> compile-time reflection capabilities that will allow you to generate
>> strings from enumeration constants simply and easily, without repetition
>> in the code (and without complicated X-macros).
> 
> Even for C++ scoped enumerations, each enumerator has a well defined
> numeric value that can be specified in the declaration and accessed by
> casting to an integer type.  This is part of the language-defined
> semantics of the feature, not something that the language incorrectly
> fails to hide.
> 
> I've personally found it annoying that a scoped enum can't be used as an
> array index.  (Ada's enumeration types are distinct types, more strongly
> typed than C++'s scoped enums, and they can be used as array
> indices.  Of course neither C nor C++ is Ada, nor should they be.)

Well you CAN either cast the enum to an integer, or define an array like
object that has a subscript operator that takes the scoped enum. With
that you could even define an 'array' that can ONLY be indexed with a
scoped enum.
> 
> It's difficult to extend a weakly typed feature like C's enum and make
> it reasonably type-safe without breaking things.  If C were to add a
> more strongly typed enumeration feature, it would probably make sense to
> adopt something very similar to what C++ has already done.
> 

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


#162922

FromMalcolm McLean <malcolm.arthur.mclean@gmail.com>
Date2021-10-01 14:56 -0700
Message-ID<45345f3f-90d2-4786-862c-6b544d4aa4can@googlegroups.com>
In reply to#162918
On Friday, 1 October 2021 at 21:59:04 UTC+1, Keith Thompson wrote:
> David Brown <david...@hesbynett.no> writes: 
> > 
> > For convenience (and for standard C++) you might define such an array 
> > without designated initialisers, but you are still trying to view the 
> > enumeration elements as abstract symbols, not as merely names for 
> > integer constants.
> If you're going to be doing this a lot, it probably makes sense to 
> generate the table automatically. 
> 
Often you have quite a large amount of data associated with your enums.
So it's impractical and error-prone to type it in by hand. The table will
be generated by or stored in another program, and cut and pasted into
the C source. It might then need minor edits to make it a compileable C
initialiser.
However it's far easier if you can agree on an ordering which is consistent 
between the enum and the external data source. 

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


#162932

FromDavid Brown <david.brown@hesbynett.no>
Date2021-10-02 12:21 +0200
Message-ID<sj9bqp$epd$1@dont-email.me>
In reply to#162918
On 01/10/2021 22:58, Keith Thompson wrote:
> David Brown <david.brown@hesbynett.no> writes:
>> On 30/09/2021 16:36, Malcolm McLean wrote:
>>> On Thursday, 30 September 2021 at 11:45:50 UTC+1, David Brown wrote:
>>>>
>>>> But I think that in most cases, it is not at all helpful to think about 
>>>> the underlying integer values. You get cleaner, safer, more portable 
>>>> code if you treat the enumeration constants as being abstract symbols 
>>>> that are members of the particular type without any other semantics or 
>>>> meaning.
>>>>
>>> I agree, but there are some snags. One is if you wish to print out
>>> the enum for debug purposes. It's easy enough to write printf("light
>>> %d\n", (int) lightenumval); If you have to set up an enum to string
>>> function then it's a bit clearer, but it's a huge hassle for debug.
>>> The other snag is that often you want to use the enum to index into a table
>>> of some sort. Again, you can set up a system by writing a switch, but that's
>>> likely slower and more code. 
>>
>> These are not "snags" - they are cases where the underlying integer
>> value of the enumeration constants is sometimes helpful due to the
>> limitations of the language.  Eventually, C++ will get some decent
>> compile-time reflection capabilities that will allow you to generate
>> strings from enumeration constants simply and easily, without repetition
>> in the code (and without complicated X-macros).
> 
> Even for C++ scoped enumerations, each enumerator has a well defined
> numeric value that can be specified in the declaration and accessed by
> casting to an integer type.  This is part of the language-defined
> semantics of the feature, not something that the language incorrectly
> fails to hide.
> 

Yes, I know these are well-defined as part of the C++ language.  I don't
think it is always a good thing that these are user-visible, as for many
uses I would prefer enumeration constants to be purely abstract symbols.
 Obviously you can ignore the underlying integer value and pretend they
are just symbols.  But people often write code that relies on their
integer nature (such as incrementing a variable of an enumerated type
representing a state, rather than giving the new state explicitly) in a
way that IMHO gives lazier, but poorer code.  And the fact that the
language treats enumeration types as a kind of integer, and enumeration
constants as a type of integer constant, means it is far too easy to
make mistakes in the code that are not errors according to the language,
and it also limits the compiler's analysis and optimisations.

C++ scoped enums help with some of that, and compiler flags can also
improve the safety and efficiency of enumerations in some situations.

The real limitation of C and C++ in this area, IMHO, is that there are
no reflection capabilities in the language at the moment.  There is
nothing equivalent to Ada's enumeration operators and attributes
"Image", "Value", "First", "Last", "Succ", etc.  Several of the cases
mentioned in this thread for when the underlying integer values are
useful, is precisely because of this limitation.

> I've personally found it annoying that a scoped enum can't be used as an
> array index.  (Ada's enumeration types are distinct types, more strongly
> typed than C++'s scoped enums, and they can be used as array
> indices.  Of course neither C nor C++ is Ada, nor should they be.)
> 

I agree entirely.  I also agree that Ada is a different language with
different balances from both C and C++ - however, languages can take
inspiration from each other and copy or adapt useful features.  (I don't
think reflection capabilities are something that C should adopt here,
but they /are/ appropriate for C++.)


> It's difficult to extend a weakly typed feature like C's enum and make
> it reasonably type-safe without breaking things.  If C were to add a
> more strongly typed enumeration feature, it would probably make sense to
> adopt something very similar to what C++ has already done.
> 

Yes.  But it is possible to go further than C++ has.

>> In the meantime, C99, and C++ with gcc extensions (unfortunately not
>> standard), let you write:
>>
>>
>> typedef enum Colours { red, green, blue } Colours;
>>
>> extern const char * const colour_names[];
>> const char * const colour_names[] = {
>>     [red] = "red",
>>     [green] = "green",
>>     [blue] = "blue",
>> };
>>
>> This does not use or rely on underlying integer values in any way -
>> there is no need even to have the same order in the array definition as
>> in the enumeration.
>>
>> For convenience (and for standard C++) you might define such an array
>> without designated initialisers, but you are still trying to view the
>> enumeration elements as abstract symbols, not as merely names for
>> integer constants.
> 
> If you're going to be doing this a lot, it probably makes sense to
> generate the table automatically.
> 

Yes.  I mentioned "X macros", which are a common way to handle such
things.  External preprocessing can also sometimes be useful, especially
if the enumeration contents are from an external source.  But it would
be nice to be able to handle this all more naturally within the language
(and I'm thinking C++ more than C) in a less manual fashion.

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


#162882

Fromscott@slp53.sl.home (Scott Lurndal)
Date2021-09-30 14:47 +0000
Message-ID<V5k5J.59463$6U3.29625@fx43.iad>
In reply to#162875
David Brown <david.brown@hesbynett.no> writes:
>On 30/09/2021 03:25, Keith Thompson wrote:
>> David Brown <david.brown@hesbynett.no> writes:
>> [...]
>>> With strong enumerations, you shouldn't even be thinking of them as
>>> having an integer value - it doesn't make sense to compare the "value"
>>> of a "colours" enumeration element with one from a "lights" enumeration.
>>>  That is a large part of the point of having better enumeration types
>>> than were available in C.
>> 
>> C++ scoped enumeration types do have well-defined integer
>> representations.  You can even specify them in the declaration:
>> 
>>     enum class foo { zero = 0, one = 1 };
>> 
>> There's no implicit conversion from foo to int, but you can use a cast;
>> for example (int)foo::zero == 0.
>> 
>
>Sure - and for some use-cases that might be useful.
>
>But I think that in most cases, it is not at all helpful to think about
>the underlying integer values.  You get cleaner, safer, more portable
>code if you treat the enumeration constants as being abstract symbols
>that are members of the particular type without any other semantics or
>meaning.

But then you need something akin to the Pascal "PRED" and "SUCC" functions.

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


#162885

FromMalcolm McLean <malcolm.arthur.mclean@gmail.com>
Date2021-09-30 10:10 -0700
Message-ID<af0db3eb-7679-49ab-bc45-0675c1b5368fn@googlegroups.com>
In reply to#162882
On Thursday, 30 September 2021 at 15:47:29 UTC+1, Scott Lurndal wrote:
> David Brown <david...@hesbynett.no> writes: 
> >On 30/09/2021 03:25, Keith Thompson wrote: 
> >> David Brown <david...@hesbynett.no> writes: 
> >> [...] 
> >>> With strong enumerations, you shouldn't even be thinking of them as 
> >>> having an integer value - it doesn't make sense to compare the "value" 
> >>> of a "colours" enumeration element with one from a "lights" enumeration. 
> >>> That is a large part of the point of having better enumeration types 
> >>> than were available in C. 
> >> 
> >> C++ scoped enumeration types do have well-defined integer 
> >> representations. You can even specify them in the declaration: 
> >> 
> >> enum class foo { zero = 0, one = 1 }; 
> >> 
> >> There's no implicit conversion from foo to int, but you can use a cast; 
> >> for example (int)foo::zero == 0. 
> >> 
> > 
> >Sure - and for some use-cases that might be useful. 
> > 
> >But I think that in most cases, it is not at all helpful to think about 
> >the underlying integer values. You get cleaner, safer, more portable 
> >code if you treat the enumeration constants as being abstract symbols 
> >that are members of the particular type without any other semantics or 
> >meaning.
> But then you need something akin to the Pascal "PRED" and "SUCC" functions.
>
Yes, that's another case I forgot.
You often want to iterate over all the values of an enum.

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


#162888

FromDavid Brown <david.brown@hesbynett.no>
Date2021-10-01 09:24 +0200
Message-ID<sj6d3o$fej$1@dont-email.me>
In reply to#162882
On 30/09/2021 16:47, Scott Lurndal wrote:
> David Brown <david.brown@hesbynett.no> writes:
>> On 30/09/2021 03:25, Keith Thompson wrote:
>>> David Brown <david.brown@hesbynett.no> writes:
>>> [...]
>>>> With strong enumerations, you shouldn't even be thinking of them as
>>>> having an integer value - it doesn't make sense to compare the "value"
>>>> of a "colours" enumeration element with one from a "lights" enumeration.
>>>>  That is a large part of the point of having better enumeration types
>>>> than were available in C.
>>>
>>> C++ scoped enumeration types do have well-defined integer
>>> representations.  You can even specify them in the declaration:
>>>
>>>     enum class foo { zero = 0, one = 1 };
>>>
>>> There's no implicit conversion from foo to int, but you can use a cast;
>>> for example (int)foo::zero == 0.
>>>
>>
>> Sure - and for some use-cases that might be useful.
>>
>> But I think that in most cases, it is not at all helpful to think about
>> the underlying integer values.  You get cleaner, safer, more portable
>> code if you treat the enumeration constants as being abstract symbols
>> that are members of the particular type without any other semantics or
>> meaning.
> 
> But then you need something akin to the Pascal "PRED" and "SUCC" functions.
> 

Sometimes, yes, that would be nice.  Often, however, your code is safer
if you /don't/ have such features.  It might seem like a good idea to
have "go to next state" in your state machine, rather than giving the
next state explicitly, but you'll regret it when someone adds a new
state to the enumeration somewhere in the middle.

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


#162871

FromAndrey Tarasevich <andreytarasevich@hotmail.com>
Date2021-09-29 12:43 -0700
Message-ID<sj2fkt$nd7$1@dont-email.me>
In reply to#162867
On 9/29/2021 7:03 AM, Bart wrote:
>>
>> It is not remotely surprising - in order to be able to use identifiers
>> within a nested code structure (I'm using that as a general term, not
>> just "struct") of some sort, you need to be "inside" the structure, in
>> the scope of a "using" clause, or you need to give the qualified name.
> 
> Yeah, you're right. It would be tricky anyway, because it can't be 
> sorted using normal name resolution rules, since it relies on type info 
> which may not be dealt with until a subsequent stage.
> 

C++ already has a remotely similar feature, when the type of the LHS of 
the assignment/initialization affects the treatment of the RHS

   // A set of overloaded functions
   void foo();
   void foo(int);
   void foo(double);

   int main()
   {
     void (*ptr)(double) = foo;
     // Valid, automatically selects `void foo(double)`
   }

In this example the process guided by the type on the LHS is not name 
lookup, but overload resolution for the RHS. But the point is that the 
general idea of passing type info from the LHS to the RHS is already 
present in the language.

It can probably be done for enums as well, as in your example. But as it 
has been noted above, the value of such feature would be rather small.

-- 
Best regards,
Andrey Tarasevich

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


#162864

FromBranimir Maksimovic <branimir.maksimovic@gmail.com>
Date2021-09-29 03:40 +0000
Message-ID<TeR4J.59818$jm6.2396@fx07.iad>
In reply to#162859
On 2021-09-28, John Bode <jfbode1029@gmail.com> wrote:
> On 9/27/21 12:39 PM, Thiago Adams wrote:
>> I was wondering if we have some reason to
>> disallow redeclaration of identical (name/value) enumerators.
>> 
>> enum E1 {  A = 1 };
>> enum E2 {  A = 1 };
>> 
>
> Unlike structs and unions, each enum type is not its own
> namespace and enumeration constants belong to the "ordinary
> identifiers" namespace.
namespace is not needed for grown up men/women.
Just put prefix and voila :P


-- 

7-77-777
Evil Sinner!

[toc] | [prev] | [standalone]


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

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


csiph-web