Correct C++ tutorial part 3 "Intro to loops" available (Windows, mingw/msvc/std)

Discussion in 'C++' started by Alf P. Steinbach, Jan 19, 2005.

  1. The third part of my attempted Correct C++ tutorial is now available,
    although for now only in Word format (use free Open Office if no Word),
    and also, it's not yet been extensively reviewed -- comments welcome!

    "Intro to loops"
    <url: http://home.no.net/dubjai/win32cpptut/w32cpptut_01_03.doc>

    As before I expect that here's mental food and technical points that
    we can strongly disagree about, for both newbie and the experienced.

    And as before the point of inviting comments is to _fix_ anything
    incorrect, or the presentation, or whatever; your input is valuable.

    The first two parts, "Hello, world!" and "Variables", are available
    both as Word docs and (now reasonably structured! ;-)) HTML at

    <url: http://home.no.net/dubjai/win32cpptut/html/>

    Again, re part 2, thanks to Stephan Brönniman for helping with the
    conversion from Word to HTML, and helpful comments & corrections.


    [I inadvertently posted this message to comp.std.c++: darn that mouse!
    If any of the moderators read this and can cancel that, please.]

    --
    A: Because it messes up the order in which people normally read text.
    Q: Why is it such a bad thing?
    A: Top-posting.
    Q: What is the most annoying thing on usenet and in e-mail?
     
    Alf P. Steinbach, Jan 19, 2005
    #1
    1. Advertising

  2. Hi Alf,

    In the chapter 8 maybe: "Always use an integral type such as int for a
    loop control variable" is 'to strong'. I think to something like:
    "chose the desired precision when dealing with floats and avoid 'equal'
    operators".

    Another pitfall could be: for( unsigned int i = 5; i >= 0; --i ) { ...
    }

    Best regards,
    Bogdan Sintoma
     
    Bogdan Sintoma, Jan 19, 2005
    #2
    1. Advertising

  3. * Alf P. Steinbach:
    > The third part of my attempted Correct C++ tutorial is now available,
    > although for now only in Word format (use free Open Office if no Word),
    > and also, it's not yet been extensively reviewed -- comments welcome!
    >
    > "Intro to loops"
    > <url: http://home.no.net/dubjai/win32cpptut/w32cpptut_01_03.doc>
    >
    > As before I expect that here's mental food and technical points that
    > we can strongly disagree about, for both newbie and the experienced.
    >
    > And as before the point of inviting comments is to _fix_ anything
    > incorrect, or the presentation, or whatever; your input is valuable.


    Well, I discovered one Big Blunder myself! :-o

    In section 4, "[Pitfall:] Using assignment instead of comparision",
    I described an if-condition as accepting non-bool values because it
    converted bool to numerical zero / non-zero. That was correct as an
    effective belief, and may be the way it is in C, but it's not how it
    actually works in C++. In C++ the same _effect_ is achieved by having
    implicit conversion of non-bool values (zero, non-zero) to bool.

    Now corrected...

    --
    A: Because it messes up the order in which people normally read text.
    Q: Why is it such a bad thing?
    A: Top-posting.
    Q: What is the most annoying thing on usenet and in e-mail?
     
    Alf P. Steinbach, Jan 20, 2005
    #3
  4. * Bogdan Sintoma:
    > Hi Alf,
    >
    > In the chapter 8 maybe: "Always use an integral type such as int for a
    > loop control variable" is 'to strong'. I think to something like:
    > "chose the desired precision when dealing with floats and avoid 'equal'
    > operators".


    Well, here's my reasoning:

    * If you use e.g. 'double' as a loop control variable (counter), you
    either use integer update (e.g. increment) or non-integer update.

    * If you use integer update you should use integer type for the
    variable.

    * If you use non-integer update you're in trouble, and/or are
    doing things in a needlessly complicated way; either way the
    solution is to use integer type for the loop control variable.

    Additionally, it would take much text to explain how to compare
    floating point values "safely", and what degree of safety can be
    achieved (it's an advanced topic one can write a whole book about...).

    Does this make sense?



    > Another pitfall could be: for( unsigned int i = 5; i >= 0; --i ) { ...
    > }


    Yes, thanks.

    My thinking here has been to introduce only the bare minimum of
    _general_ functionality, not things that are really only optimization or
    only useful in special cases, and so no 'unsigned' yet, only 'int'.

    But perhaps that pitfall is so common that it deserves to be mentioned
    even at this early stage?

    --
    A: Because it messes up the order in which people normally read text.
    Q: Why is it such a bad thing?
    A: Top-posting.
    Q: What is the most annoying thing on usenet and in e-mail?
     
    Alf P. Steinbach, Jan 20, 2005
    #4
  5. Alf P. Steinbach wrote:
    > * Bogdan Sintoma:
    > > Hi Alf,
    > >
    > > In the chapter 8 maybe: "Always use an integral type such as int

    for a
    > > loop control variable" is 'to strong'. I think to something like:
    > > "chose the desired precision when dealing with floats and avoid

    'equal'
    > > operators".

    >
    > Well, here's my reasoning:
    >
    > * If you use e.g. 'double' as a loop control variable (counter),

    you
    > either use integer update (e.g. increment) or non-integer update.

    Well, it could be situations when a loop control variable isn't really
    a counter. Double as control variable and increment (or decrement)
    isn't a smart choice :) (GotW #67 ;) )

    >
    > * If you use integer update you should use integer type for the
    > variable.

    Agree.

    >
    > * If you use non-integer update you're in trouble, and/or are
    > doing things in a needlessly complicated way; either way the
    > solution is to use integer type for the loop control variable.

    Let's say that you have to simulate some process. And this process must
    run until some variable (e.g some cumulated errors) exceed some level.
    Using this variable as a loop control variable could be more
    appropriate than converting (rounding) it and the limit to some integer
    value.

    Anyway, I just wand to say something like "never say never" :)

    >
    > Additionally, it would take much text to explain how to compare
    > floating point values "safely", and what degree of safety can be
    > achieved (it's an advanced topic one can write a whole book

    about...).
    >

    That's true.

    > Does this make sense?
    >
    >
    > > Another pitfall could be: for( unsigned int i = 5; i >= 0; --i ) {

    ....
    > > }

    >
    > Yes, thanks.
    >
    > My thinking here has been to introduce only the bare minimum of
    > _general_ functionality, not things that are really only optimization

    or
    > only useful in special cases, and so no 'unsigned' yet, only 'int'.
    >
    > But perhaps that pitfall is so common that it deserves to be

    mentioned
    > even at this early stage?
    >


    Not if it is just me that say so :).
    But, size_t is unsigned, isn't it? Should I write the pitfall as:
    for( vector<int>::size_type i = (v.size()-1); i >= 0; --i ){...} ? :)
     
    Bogdan Sintoma, Jan 20, 2005
    #5
  6. "Alf P. Steinbach" <> wrote in message
    news:...
    > The third part of my attempted Correct C++ tutorial is now available,
    > although for now only in Word format (use free Open Office if no Word),
    > and also, it's not yet been extensively reviewed -- comments welcome!
    >
    > "Intro to loops"
    > <url: http://home.no.net/dubjai/win32cpptut/w32cpptut_01_03.doc>
    >
    > As before I expect that here's mental food and technical points that
    > we can strongly disagree about, for both newbie and the experienced.
    >
    > And as before the point of inviting comments is to _fix_ anything
    > incorrect, or the presentation, or whatever; your input is valuable.
    >
    > The first two parts, "Hello, world!" and "Variables", are available
    > both as Word docs and (now reasonably structured! ;-)) HTML at
    >
    > <url: http://home.no.net/dubjai/win32cpptut/html/>
    >
    > Again, re part 2, thanks to Stephan Brvnniman for helping with the
    > conversion from Word to HTML, and helpful comments & corrections.
    >
    >
    > [I inadvertently posted this message to comp.std.c++: darn that mouse!
    > If any of the moderators read this and can cancel that, please.]
    >
    > --
    > A: Because it messes up the order in which people normally read text.
    > Q: Why is it such a bad thing?
    > A: Top-posting.
    > Q: What is the most annoying thing on usenet and in e-mail?


    May I ask why you chose to do loops and then the IF statement, instead of
    the other way around?

    IMO it would have been more clear to explain IF, the go onto a loop, then
    briefly do IF and then go into more detail later on (in your next part I
    presume).

    I find these tutorials very nice, and reading through them has been very
    pleasant - thank you for writing these!

    --
    =========
    Comp Whizz
    =========
    (The C++ beginner)
     
    Computer Whizz, Jan 20, 2005
    #6
  7. * Bogdan Sintoma:
    > Alf P. Steinbach wrote:
    > > * Bogdan Sintoma:
    > > > Hi Alf,
    > > >
    > > > In the chapter 8 maybe: "Always use an integral type such as int
    > > > for a loop control variable" is 'to strong'. I think to something
    > > > like: "chose the desired precision when dealing with floats and
    > > > avoid 'equal' operators".

    > >
    > > Well, here's my reasoning:
    > >
    > > * If you use e.g. 'double' as a loop control variable (counter),
    > > you either use integer update (e.g. increment) or non-integer
    > > update.

    >
    > Well, it could be situations when a loop control variable isn't really
    > a counter.


    Does it matter whether it counts or not?


    > Double as control variable and increment (or decrement)
    > isn't a smart choice :) (GotW #67 ;) )


    At first reading that seems like we're in agreement, but on second
    reading I'm not sure I grok that statement -- and what's
    <url: http://www.gotw.ca/gotw/067.htm> got to do with this?


    [snip]
    > > * If you use non-integer update you're in trouble, and/or are
    > > doing things in a needlessly complicated way; either way the
    > > solution is to use integer type for the loop control variable.

    >
    > Let's say that you have to simulate some process. And this process must
    > run until some variable (e.g some cumulated errors) exceed some level.
    > Using this variable as a loop control variable could be more
    > appropriate than converting (rounding) it and the limit to some integer
    > value.


    One example could be to iteratively determine the square root of n,
    using a 'double' variable 'root' and binary search. But now I don't
    think of that variable as a loop control variable. Trying to pin down
    what I mean, which I think is the general accepted meaning: in each
    iteration except the first the value of a loop control variable depends
    (only) on the previous value of that variable, the values in different
    iterations except possibly the last one are different, and the loop
    condition depends on that variable and possibly more.

    The WikiPedia definition of 'loop counter' is somewhat similar, at
    <url: http://en.wikipedia.org/wiki/Loop_counter>, but I don't like using
    the word "counter" which implies a more restricted meaning.

    On the other hand, using the Newton/Raphson algorithm 'root' would
    qualify as a loop control variable, with both the above definitions.

    So I think you're right that my advice excludes a whole general class
    of useful 'double' loop control variables.

    What could be a good way to include this information in the text,
    keeping it reasonably short and novice-level?


    [snip]
    > But, size_t is unsigned, isn't it? Should I write the pitfall as:
    > for( vector<int>::size_type i = (v.size()-1); i >= 0; --i ){...} ? :)


    Thinking about that pitfall it's part of a more general pitfall, namely
    assuming integer values exist outside the defined range.

    I think it will have to wait till a general discussion of that.

    If, when, I get to that... :)

    --
    A: Because it messes up the order in which people normally read text.
    Q: Why is it such a bad thing?
    A: Top-posting.
    Q: What is the most annoying thing on usenet and in e-mail?
     
    Alf P. Steinbach, Jan 21, 2005
    #7
  8. * Computer Whizz:
    >
    > May I ask why you chose to do loops and then the IF statement, instead of
    > the other way around?


    Well I didn't... ;-) It's like the resolution of a circular class
    dependency A <-> B by introducing abstract base classes A' and B', and
    then A <- (A' + B'), B <- (A' + B'), where "x <- y" means x depends on
    y. What I did was to first introduce a raw infinite loop (base class
    A'), which serves to introduce an unconditional jump which I think is
    the most basic and easiest-to-comprehend form, and then a simple 'if'
    (base class B'), which serves to introduce a conditional jump.

    After that a more full discussion of loops (concrete class A), done
    first because loops allow you to do interesting things.

    The next part tackles decisions in general (concrete class B).


    [snip]
    > I find these tutorials very nice, and reading through them has been very
    > pleasant - thank you for writing these!


    Thank _you_.

    --
    A: Because it messes up the order in which people normally read text.
    Q: Why is it such a bad thing?
    A: Top-posting.
    Q: What is the most annoying thing on usenet and in e-mail?
     
    Alf P. Steinbach, Jan 21, 2005
    #8
  9. Alf P. Steinbach wrote:
    > > > In the chapter 8 maybe: "Always use an integral type such as int
    > > > > for a loop control variable" is 'to strong'. I think to

    something
    > > > > like: "chose the desired precision when dealing with floats and
    > > > > avoid 'equal' operators".
    > > >
    > > > Well, here's my reasoning:
    > > >
    > > > * If you use e.g. 'double' as a loop control variable

    (counter),
    > > > you either use integer update (e.g. increment) or non-integer
    > > > update.

    > >
    > > Well, it could be situations when a loop control variable isn't

    really
    > > a counter.

    >
    > Does it matter whether it counts or not?

    Maybe, please see below.

    >
    > > Double as control variable and increment (or decrement)
    > > isn't a smart choice :) (GotW #67 ;) )

    >
    > At first reading that seems like we're in agreement, but on second
    > reading I'm not sure I grok that statement -- and what's
    > <url: http://www.gotw.ca/gotw/067.htm> got to do with this?


    You mention increment and 'doubles'. I just want to point out that
    there are float implementation that cannot exactly represent all the
    integer values from certain interval.
    And, yes, we are in agreement for 'count-controlled loops'.

    [snip]

    > One example could be to iteratively determine the square root of n,
    > using a 'double' variable 'root' and binary search. But now I don't
    > think of that variable as a loop control variable. Trying to pin

    down
    > what I mean, which I think is the general accepted meaning: in each
    > iteration except the first the value of a loop control variable

    depends
    > (only) on the previous value of that variable, the values in

    different
    > iterations except possibly the last one are different, and the loop
    > condition depends on that variable and possibly more.
    >
    > The WikiPedia definition of 'loop counter' is somewhat similar, at
    > <url: http://en.wikipedia.org/wiki/Loop_counter>, but I don't like

    using
    > the word "counter" which implies a more restricted meaning.
    >

    Yes, that's true, but let me cite the same source:
    http://en.wikipedia.org/wiki/Conditional_branching#Loops
    "A loop is a sequence of statements which is specified once but which
    may be carried out several times in succession. The code "inside" the
    loop (the body of the loop, shown below as xxx) is obeyed a specified
    number of times, or once for each of a collection of items, or until
    some condition is met."
    And further 'count-controlled' and 'condition-controlled' loops are
    defined.
    The c++ 'for' statement can be used in both cases.
    (Actually "the standard" - 6.5.3.1 - define the 'for' statement in
    equivalence with the 'while' statement)

    > On the other hand, using the Newton/Raphson algorithm 'root' would
    > qualify as a loop control variable, with both the above definitions.
    >
    > So I think you're right that my advice excludes a whole general class
    > of useful 'double' loop control variables.
    >

    Thanks :)

    > What could be a good way to include this information in the text,
    > keeping it reasonably short and novice-level?
    >

    Well, that's not so easy :).
    What about: "Don't use floating point types as loops control variable,
    unless you really know what you are doing." :)

    >
    > [snip]
    > > But, size_t is unsigned, isn't it? Should I write the pitfall as:
    > > for( vector<int>::size_type i = (v.size()-1); i >= 0; --i ){...} ?

    :)
    >
    > Thinking about that pitfall it's part of a more general pitfall,

    namely
    > assuming integer values exist outside the defined range.
    >

    Agree.

    > I think it will have to wait till a general discussion of that.
    >
    > If, when, I get to that... :)

    Just erase the "if" ;).

    Best regards,
    Bogdan
     
    Bogdan Sintoma, Jan 21, 2005
    #9
  10. * Bogdan Sintoma:
    > What about: "Don't use floating point types as loops control variable,
    > unless you really know what you are doing." :)


    Done.

    Thanks,

    - Alf

    --
    A: Because it messes up the order in which people normally read text.
    Q: Why is it such a bad thing?
    A: Top-posting.
    Q: What is the most annoying thing on usenet and in e-mail?
     
    Alf P. Steinbach, Jan 23, 2005
    #10
  11. Alf P. Steinbach

    Attila Feher Guest

    Alf P. Steinbach wrote:
    > * Bogdan Sintoma:
    >> Hi Alf,
    >>
    >> In the chapter 8 maybe: "Always use an integral type such as int for
    >> a loop control variable" is 'to strong'. I think to something like:
    >> "chose the desired precision when dealing with floats and avoid
    >> 'equal' operators".

    >
    > Well, here's my reasoning:
    >
    > * If you use e.g. 'double' as a loop control variable (counter), you
    > either use integer update (e.g. increment) or non-integer update.


    Yeah. And you use either C++ or not to write it. ;-)

    > * If you use integer update you should use integer type for the
    > variable.


    Why? You have introduced your lines with the word reasoning, but I see no
    reason told for this statement.

    > * If you use non-integer update you're in trouble, and/or are
    > doing things in a needlessly complicated way; either way the
    > solution is to use integer type for the loop control variable.


    Again, no reasoning. Using floating point numbers where floating point
    operations are needed is (IMHO) not needlessly complicated for two reasons:
    1.) Read the beginning of the sentence, 2.) using floating point is only
    complicated until you learn it.

    > Additionally, it would take much text to explain how to compare
    > floating point values "safely", and what degree of safety can be
    > achieved (it's an advanced topic one can write a whole book about...).


    That is the only reasoning in your text. Which suggests that instead of
    making up a rule which is not supported by any real arguments (original
    says: "Always use an integral type such as int for a loop control variable",
    so it effectively rules out iterators as well as a billion other things) why
    not tell simply what you have said above: floating point arithmetics is a
    topic of its own, not something which belongs to a beginner's tutorial?

    > Does this make sense?


    Only the last sentence. The rest makjes sense too, as an opinion, but not
    as reasoning. ;-)

    >> Another pitfall could be: for( unsigned int i = 5; i >= 0; --i ) {
    >> ... }

    >
    > Yes, thanks.
    >
    > My thinking here has been to introduce only the bare minimum of
    > _general_ functionality, not things that are really only optimization
    > or only useful in special cases, and so no 'unsigned' yet, only 'int'.
    >
    > But perhaps that pitfall is so common that it deserves to be mentioned
    > even at this early stage?


    There is somewhere on the net (was it Stroustrups pages?) a paper on why not
    ot use unsigned variables for most of the things. So probably you want to
    introduce that opportunity later, so people don't fly off course on a
    tangent and start playing around with unsigned values.

    --
    Attila aka WW
     
    Attila Feher, Jan 27, 2005
    #11
  12. * Attila Feher:
    > Alf P. Steinbach wrote:
    > > * Bogdan Sintoma:
    > >> Hi Alf,
    > >>
    > >> In the chapter 8 maybe: "Always use an integral type such as int for
    > >> a loop control variable" is 'to strong'. I think to something like:
    > >> "chose the desired precision when dealing with floats and avoid
    > >> 'equal' operators".

    > >
    > > Well, here's my reasoning:
    > >
    > > * If you use e.g. 'double' as a loop control variable (counter), you
    > > either use integer update (e.g. increment) or non-integer update.

    >
    > Yeah. And you use either C++ or not to write it. ;-)


    That's the context: a numeric loop control variable, with two mutually
    excluding and exhaustive possibilities then discussed.


    > > * If you use integer update you should use integer type for the
    > > variable.

    >
    > Why? You have introduced your lines with the word reasoning, but I see no
    > reason told for this statement.


    It seems to boil down to two issues: why it's not a good idea to use a
    misleading type (maintainability), and whether a floating point type can
    always represent all values of an integral type exactly (technical).


    > > * If you use non-integer update you're in trouble, and/or are
    > > doing things in a needlessly complicated way; either way the
    > > solution is to use integer type for the loop control variable.

    >
    > Again, no reasoning. Using floating point numbers where floating point
    > operations are needed is (IMHO) not needlessly complicated for two reasons:
    > 1.) Read the beginning of the sentence, 2.) using floating point is only
    > complicated until you learn it.


    Yes, to the latter two sentences. I wonder whether you are happy with
    the resolution of that issue as it turned out in the rest of the thread?
    That is, adding the parenthetical expression "unless you really know
    what you're doing"?


    > > Additionally, it would take much text to explain how to compare
    > > floating point values "safely", and what degree of safety can be
    > > achieved (it's an advanced topic one can write a whole book about...).

    >
    > That is the only reasoning in your text. Which suggests that instead of
    > making up a rule which is not supported by any real arguments (original
    > says: "Always use an integral type such as int for a loop control variable",
    > so it effectively rules out iterators as well as a billion other things) why
    > not tell simply what you have said above: floating point arithmetics is a
    > topic of its own, not something which belongs to a beginner's tutorial?


    Iterators and pointers as loop control variables is a good point,
    thanks.

    The discussion above was trapped in the implicit context of numeric loop
    control variables.

    Possibly I should add the word "numeric" in the advice. But I think it
    would then hang in thin air, not related to the rest of the discussion.
    Suggestions?

    --
    A: Because it messes up the order in which people normally read text.
    Q: Why is it such a bad thing?
    A: Top-posting.
    Q: What is the most annoying thing on usenet and in e-mail?
     
    Alf P. Steinbach, Jan 27, 2005
    #12
  13. Alf P. Steinbach

    Attila Feher Guest

    Alf P. Steinbach wrote:
    [SNIP]
    >>> * If you use integer update you should use integer type for the
    >>> variable.

    >>
    >> Why? You have introduced your lines with the word reasoning, but I
    >> see no reason told for this statement.

    >
    > It seems to boil down to two issues: why it's not a good idea to use a
    > misleading type (maintainability), and whether a floating point type
    > can always represent all values of an integral type exactly
    > (technical).


    Why would a floating point type misleading if I need a floating point value?
    Furthermore - on the same note - why would I care about it representing or
    not integer values, if I needed a floating point one in the first place?

    [SNIP]
    > Yes, to the latter two sentences. I wonder whether you are happy with
    > the resolution of that issue as it turned out in the rest of the
    > thread? That is, adding the parenthetical expression "unless you
    > really know what you're doing"?


    That is one way to put it. :) But I guess there is another and probably
    more important reason/cause: do you need a floating point iteration or not?
    :) And then comes the know what you do, do what you know. ;-)

    [SNIP]
    > Iterators and pointers as loop control variables is a good point,
    > thanks.


    No problemo. :)

    > The discussion above was trapped in the implicit context of numeric
    > loop control variables.


    And it possibly should for that very-beginner part, but IMHO the rule itself
    may need to be worded differently. So that it suggests to the reader that
    the rules is supposed to say: do not use floating point unless you really
    need it (IMHO this goes not only for loops), so basically tell what is
    wrong, instead of identifying what is right. Because limiting the possible
    types (in this case/stage) will rule out valid cases, valid cases you did
    not introduce yet for a reason.

    > Possibly I should add the word "numeric" in the advice. But I think
    > it would then hang in thin air, not related to the rest of the
    > discussion. Suggestions?


    What I wrote above could probably be worded.

    Loops can do (at least) counting and iterating, not taking into account the
    "abuses" of them, like when a do {} while(0); loop (with breaks inside) is
    used instead of a local try-catch...

    So the loop variable in those non-abuse cases can mean a numeric value
    (counting), and index value (addressing into containers using the array
    access) or an iterator. A loop walking a linked list (with the loop
    variable being a pointer to one list element) is (IMHO) a special case of
    iteration.

    My point is: there can be numerous other (legal and "good design") uses of
    loops, which the current rule rules out. If the rule could be worded to
    only say what not to do, the "unknown number of other legal uses" would not
    be affected by it.

    --
    Attila aka WW
     
    Attila Feher, Jan 27, 2005
    #13
  14. * Attila Feher:
    >
    > If the rule could be worded to only say what not to do, the
    > "unknown number of other legal uses" would not be affected by it.


    Done.

    New wording:

    <quote>
    That's partly why the program uses the integer type int for the counter,
    instead of double (thanks to Bogdan Sintoma and Attila Feher for good advice
    concerning the wording here):

    * Don't use a floating point type such as double for a loop control variable
    (unless you really know what you're doing).

    If you do use e.g. double you'll get accumulated rounding errors, and
    probably end up with a program that loops one less time than it "should"
    and results that are very wildly off the mark.
    </quote>

    Thanks,

    - Alf

    --
    A: Because it messes up the order in which people normally read text.
    Q: Why is it such a bad thing?
    A: Top-posting.
    Q: What is the most annoying thing on usenet and in e-mail?
     
    Alf P. Steinbach, Feb 1, 2005
    #14
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Alf P. Steinbach
    Replies:
    7
    Views:
    3,092
    chris
    Jan 24, 2005
  2. Alf P. Steinbach
    Replies:
    10
    Views:
    783
    Alf P. Steinbach
    Feb 23, 2005
  3. Alf P. Steinbach
    Replies:
    2
    Views:
    539
    Alf P. Steinbach
    Feb 22, 2005
  4. Alf P. Steinbach
    Replies:
    0
    Views:
    587
    Alf P. Steinbach
    Feb 22, 2005
  5. Alf P. Steinbach
    Replies:
    25
    Views:
    986
    Thomas Hansen
    Apr 11, 2005
Loading...

Share This Page