• Anonymous (unregistered) in reply to V.

    Am I the only one (maybe missing prior post) that sees this flaw with the for (;;) construct:

    for (int I = 0; I < StupidSlowUpperLimit(); ++I) {
        // Stuff
    };

    At least in Pascal

    FOR I := 0 TO StupidSlowUpperLimit() DO BEGIN
    END;

    you are guaranteed the limits are only evaluated once on entry. The same applies to the code in this post (although that is its only redeeming feature).

    What C and C-like languages need is a proper "loop <statement>" statement like (?Pascal) Modula-2's LOOP ... END; and then use break to leave the loop whenever we need to. I think "foreach <ident> in <generator> ..." is the way forward. The for (;;) construct is simply an artefact of when computers were slow, compilers were dumb and C was just a refined version of a macro assembler.

  • Anonymous (unregistered) in reply to Anonymous
    Anonymous:
    Am I the only one (maybe missing prior post) that sees this flaw with the for (;;) construct:

    for (int I = 0; I < StupidSlowUpperLimit(); ++I) {
        // Stuff
    };

    At least in Pascal

    FOR I := 0 TO StupidSlowUpperLimit() DO BEGIN
    END;

    you are guaranteed the limits are only evaluated once on entry. The same applies to the code in this post (although that is its only redeeming feature).

    What C and C-like languages need is a proper "loop <statement>" statement like (?Pascal) Modula-2's LOOP ... END; and then use break to leave the loop whenever we need to. I think "foreach <ident> in <generator> ..." is the way forward. The for (;;) construct is simply an artefact of when computers were slow, compilers were dumb and C was just a refined version of a macro assembler.


    Damn, it should say (and does on my screen)

    </generator></ident></statement> for (int I = 0; I < StupidSlowUpperLimit(); ++I) {

        // Stuff

    };

  • mugs (unregistered) in reply to Anonymous

    Anonymous:
    Am I the only one (maybe missing prior post) that sees this flaw with the for (;;) construct:

    for (int I = 0; I < StupidSlowUpperLimit(); ++I) {
        // Stuff
    };

    At least in Pascal

    FOR I := 0 TO StupidSlowUpperLimit() DO BEGIN
    END;

    you are guaranteed the limits are only evaluated once on entry. The same applies to the code in this post (although that is its only redeeming feature).

    You could just assign StupidSlowUpperLimit() to a variable and use that variable as the upper limit of the loop to accomplish the same thing...



    What C and C-like languages need is a proper "loop <STATEMENT>" statement like (?Pascal) Modula-2's LOOP ... END; and then use break to leave the loop whenever we need to. I think "foreach <IDENT>in <GENERATOR>..." is the way forward. The for (;;) construct is simply an artefact of when computers were slow, compilers were dumb and C was just a refined version of a macro assembler.

    If you want to do that, just use while(true){} and then break; whenever you decide you want to break out of the loop.

  • (cs) in reply to Anonymous
    Anonymous:
    Am I the only one (maybe missing prior post) that sees this flaw with the for (;;) construct:

    for (int I = 0; I < StupidSlowUpperLimit(); ++I) {
        // Stuff
    };

    At least in Pascal

    FOR I := 0 TO StupidSlowUpperLimit() DO BEGIN
    END;

    you are guaranteed the limits are only evaluated once on entry. The same applies to the code in this post (although that is its only redeeming feature).

    What C and C-like languages need is a proper "loop <statement>" statement like (?Pascal) Modula-2's LOOP ... END; and then use break to leave the loop whenever we need to. I think "foreach <ident> in <generator> ..." is the way forward. The for (;;) construct is simply an artefact of when computers were slow, compilers were dumb and C was just a refined version of a macro assembler.


    I don't know that I would necessarily take that as a guarantee.

    I could have sworn that C and C++ had  a "loop" construct:

    do
    {
    :
    .
    } while(!false);

    or just simply

    while(!false)
    {
    :
    .
    }

    A bit more on the guarantee:

    If there truely is a guarantee (and there may be, I don't know, I don't have the spec for pascal in front of me), What if a situation arises where StupidSlowFunction() needs to be checked on each iteration of the loop? What do you do then?

    Others have said it, the for(;;) construct is very powerful. Just remember it's basically like an initialiser, a while loop and statement all wrapped into one.
    </generator></ident></statement>
  • Jonathan (unregistered) in reply to Jonas

    Jonas is right! Once you've used "foreach var in list", (I'm using it in Perl.), having to each time manually create the increment and test of a traditional C 'for' loop seems as silly as being forced to write '5.2 + int_to_float( 3);' instead of '5.2 + 3'. It;'s drudgery -- let the computer do it!

    While creating a whole new dependency for all your code, plus the fact the each person who sees this code is going to have to get over a WTF moment, makes this a bad decision, I think this programmer saw that a useful syntax was missing, and decided to try to supply it.

    Also, I gotta say that encapsulating this in a class instead of a macro is a good idea. Macros that make multiple use of their arguments being passed code fragments with side effects is a well-known and irritating gotcha. This approach protects you for this.

  • (cs) in reply to J Drakes
    Anonymous:

    I bet that every time we read <font color="#848284">for (int i=1;i<=4;i++) </font><font color="#000000">we are really reading  <font color="#848284">for .. i..1..4 </font></font><font color="#000000">, filtering out everything else.</font>



    Nope.  I see it as int i=1 is the start condition, i<=4 is the continuation condition, and i++ is the incremental condition.  But that would mean you understand what the for loop was truly designed for!  Programming is all about being able to wrap your head around constructs and the unique syntax of the language, not to force it to do something it wasn't designed to do.  I bet you've never used a language like Ocaml where there are no loops, they're all recursions!  Or MatLab, which doesn't use loops at all, but arrays (and you can apply boolean conditions to these arrays).  Good luck with Prolog!  Go back to using VB if you can't handle a simple for loop or even a foreach loop.
  • i (unregistered)

    C Pound?

  • (cs) in reply to i
    Anonymous:
    C Pound?


    A Joke. A reference to some post made way in the past, before the advent of horrible forum software. Back in the good ol' days.


  • Franco (unregistered) in reply to Charles Nadolski

    Man, you must be joking, did you read the post at all? it was clearly meant in a perceptual filtering sense.  The guy is talking about expressiveness, not idioms.

    Charles Nadolski:
    Anonymous:

    I bet that every time we read <FONT color=#848284>for (int i=1;i<=4;i++) </FONT><FONT color=#000000>we are really reading  <FONT color=#848284>for .. i..1..4 </FONT></FONT><FONT color=#000000>, filtering out everything else.</FONT>



    Nope.  I see it as int i=1 is the start condition, i<=4 is the continuation condition, and i++ is the incremental condition.  But that would mean you understand what the for loop was truly designed for!  Programming is all about being able to wrap your head around constructs and the unique syntax of the language, not to force it to do something it wasn't designed to do.  I bet you've never used a language like Ocaml where there are no loops, they're all recursions!  Or MatLab, which doesn't use loops at all, but arrays (and you can apply boolean conditions to these arrays).  Good luck with Prolog!  Go back to using VB if you can't handle a simple for loop or even a foreach loop.
  • (cs) in reply to Charles Nadolski

    Charles Nadolski: "Nope. I see it as int i=1 is the start condition, i<=4 is the continuation condition, and i++ is the incremental condition."

    Yep - and the problem is if it got mistyped as

    (int i=1;l<=4;i++)

    (and that managed to compile), you'd probably still see the same, because you know what it should be.

    "Programming is all about being able to wrap your head around constructs and the unique syntax of the language, not to force it to do something it wasn't designed to do."

    Certainly. But it's also about attempting to minimise errors. The C-style for-loop construct is marvellously general - the language has no need for the while() {} construct at all. But if within the language (which language? - OK, say C++), there existed a "foreach(x; 1:4)" type loop construct, and the generalised for(;;) construct was used only for those cases that that didn't match, then I'd expect a reduction in the number of bugs.

  • (cs) in reply to Tallies

    <font face="Tahoma" size="2">From http://www.codeproject.com/useritems/ForCSharp.asp

    "For such a simple counting function, the for loop is a bit of overkill syntacticly. The problem is that this syntax is a roach point. What is a roach? A roach is a bug that recurs often. A roach point, is a place that roaches breed. Developers moving into C# from other languages very often make mistakes in writing this function. Instead of i <= 5, they write i = 5, or i < 5. A simple mistake, but a very common one. Another common mistake is this - lets use a 0 based loop. 0 to 4 - quick - what changes need to be made to count from 0 to 4? Did you have to think about this at all? If so - poof theres room for a roach."


    OK, what fucknut decides to call something a "roach point?"  WTF?
    </font>

  • (cs) in reply to TiredCoder

    and the main(I think) author  of the Indy Project, wich is pretty good stuff... Though still coded Delphi Style. Actually it is Delphi.

  • Spudley (unregistered) in reply to wtijsma

    Of course, it's worth knowing that there's a bunch of people who've used this technique in Perl to allow you to write your Perl programs in Latin.

    As it says on the website:  "If you have to ask why, then the answer probably won't make any sense to you either."  :D

     

    (just so you know, it's at http://search.cpan.org/~dconway/Lingua-Romana-Perligata-0.50/lib/Lingua/Romana/Perligata.pm )

     

  • J Drakes (unregistered) in reply to Spudley

    I wonder how much of it is a joke and how much is serious.  There really is some amazing depth in that work.

    Anonymous:

    Of course, it's worth knowing that there's a bunch of people who've used this technique in Perl to allow you to write your Perl programs in Latin.

    As it says on the website:  "If you have to ask why, then the answer probably won't make any sense to you either."  :D

     

    (just so you know, it's at http://search.cpan.org/~dconway/Lingua-Romana-Perligata-0.50/lib/Lingua/Romana/Perligata.pm )

     

  • (cs) in reply to christoofar
    christoofar:
    <font face="Tahoma" size="2">
    OK, what fucknut decides to call something a "roach point?"  WTF?
    </font>


    Someone who has smoked too much wacky-weed and thinks about nothing else but what's in his ashtray?
  • (cs) in reply to christoofar
    christoofar:
    <font face="Tahoma" size="2">OK, what fucknut decides to call something a "roach point?"  WTF?
    </font>

    It's short for "cockroaches" which are tough bugs to kill.  Just when you think you got the last one, a few more cockroaches crawl out of the cracks.

  • Timm Murray (unregistered)

    Nothing wrong with the idea. The implementation is more complex than it needs to be, and is a good example of overusing objects, but the concept is fine.  Idealy, a language would support a foreach-style for the 90% of code where array iteration is what you want, and a for-style for the last 10% where you need the extra flexibility.


    In fact, a language that fully supports foreach and a simple list-building construct can be more efficient.  That's because you give the compiler more information about what you're trying to do.  Loop unrolling optimization would be far easier with foreach than for.


    This is simply how new programming languages are developed--i.e., anaylize what common tasks are being done in current languages, and make them easier.  Array iteration is a very common task, so creating syntax to make it easier is an advancement of a language in general.  This is also why we have things like garbage collection in modern implementations.


    Of course, the orginal code posted wouldn't be optimized very well without hooking into a the compiler.  That ammount of effort probably wouldn't be worth it.

  • (cs)

    Big sigh.  This programmer should be taken out back and flogged, shot and dismembered [:P]  This is unacceptable code, if you have a problem with a language's specific format, use another one.  I know 6 or 7 languages and I would never imagine using something like that to get around a for loop!

  • (cs)

    My theory on this is that the progrmmer want to learn about writing an IEnumerator class, and chose a project the was a bit different than the obvious (and already written) iterating through a collection.

  • Oliver Klozoff (unregistered) in reply to Anonymous Coward
    Anonymous:
    The design is certainly *ahem* interesting, but the idea itself isn't a WTF.  Functional languages such as Ruby include such facilities,z and coded/designed correctly this isn't a bad idea with C#, especially under 2.0 with generics, iterator functions and anonymous delegates.  In fact, I *think* the power collections package contains similar ideas, though trying to look this up is not working so well for me at this moment (the site is unbelievably slow).

    Perhaps it's unbelievably slow because their code uses generics, iterators, and anonymous delegates instead of a simple for loop?

  • Oliver Klozoff (unregistered) in reply to Anonymous Coward
    Anonymous:
    The design is certainly *ahem* interesting, but the idea itself isn't a WTF.  Functional languages such as Ruby include such facilities,z and coded/designed correctly this isn't a bad idea with C#, especially under 2.0 with generics, iterator functions and anonymous delegates.  In fact, I *think* the power collections package contains similar ideas, though trying to look this up is not working so well for me at this moment (the site is unbelievably slow).

    Perhaps it's unbelievably slow because their code uses generics, iterators, and anonymous delegates instead of a simple for loop?

  • bp (unregistered) in reply to WanFactory
    Anonymous:

    Well, the WTF does have one tiny advantage over the usual way (not that it justifies it [+o(]).

    The ForTo enumerator does not have the vulnerability that an accidental i-- or i = something in the body can cause an infinite loop. Yeah, I know I need to get past my hangup of preferring definite iteration (guaranteed to terminate) over indefinite iteration but I still havent registered for the 12 step program yet... [*-)]



    You mean you wouldn't catch that running your unit tests?
    umm... you are writing unit tests right?
  • bp (unregistered)
    Alex Papadimoulis:

    [...]
    What they failed to realize, however, is how incredibly difficult it becomes for people who don't like the C# syntax to redefine their own. Just look at how much trouble the author of this code (found by Jimmy) goes through to get a loop looking like "For i = 1 To 4" ...

    /// 
    /// The ForTo class avoids confusing syntax of 
    /// "for (int i=1;i<=4;i++) {...}". This can be
    /// replaced with "foreach (int i in new ForTo(1,4)) {...}".
    /// 
    public class ForTo : IEnumerable
    {
    [...]


    Wow... who let this guy write C#? Is no one in his office saying "WTF"? Not even his boss?
  • (cs)
    Alex Papadimoulis:

    /// The ForTo class avoids confusing syntax of 
    /// "for (int i=1;i<=4;i++) {...}". This can be
    /// replaced with "foreach (int i in new ForTo(1,4)) {...}".
    


    I Love the summary comment... fantastic... hahahaha
  • (cs) in reply to bp
    Anonymous:
    Anonymous:

    Well, the WTF does have one tiny advantage over the usual way (not that it justifies it [+o(]).

    The ForTo enumerator does not have the vulnerability that an accidental i-- or i = something in the body can cause an infinite loop. Yeah, I know I need to get past my hangup of preferring definite iteration (guaranteed to terminate) over indefinite iteration but I still havent registered for the 12 step program yet... [*-)]



    You mean you wouldn't catch that running your unit tests?
    umm... you are writing unit tests right?

    Yes, of course one should write unit tests to work around the failings of the language itself. (Or asserts, if you're very confident of your looping skillz.) But you've never seen a PHP or Perl programmer (aside from language devs) waste time writing unit tests around every damned loop on the off chance that maybe, just maybe, this time foreach will mysteriously fail from comparing against l or I or j instead of i.

    Of course for loops have their uses. Why are any of you even arguing that need them, this should be self-evident. They aren't going away because they're far too widely used and too versitile to ever be useless; but here's the important part, language design is not a zero-sum game - you can have more than one looping construct, and it won't blow the compiler's mind. Well, unless it's made by Borland.

    Charles Nadolski:
    Anonymous:

    I bet that every time we read <font color="#848284">for (int i=1;i<=4;i++) </font><font color="#000000">we are really reading  <font color="#848284">for .. i..1..4 </font></font><font color="#000000">, filtering out everything else.</font>



    Nope.  I see it as int i=1 is the start condition, i<=4 is the continuation condition, and i++ is the incremental condition.  But that would mean you understand what the for loop was truly designed for!  Programming is all about being able to wrap your head around constructs and the unique syntax of the language, not to force it to do something it wasn't designed to do.  I bet you've never used a language like Ocaml where there are no loops, they're all recursions!  Or MatLab, which doesn't use loops at all, but arrays (and you can apply boolean conditions to these arrays).  Good luck with Prolog!  Go back to using VB if you can't handle a simple for loop or even a foreach loop.



    Hey Chuck, I pity your code-scanning skills if every time you see a for loop you have to sit down and analyze what operation is being performed each iteration and what operation is done to test it, then mentally compile and execute the entire loop to see what you end up with. Hope your employer pays you for that. The sad part is that the language forces us to do that every time we write a normal for loop, not just you "special needs" programmers.

    Also there's no such thing as "incremental condition". That's just the grab bag, moreso than the rest, the fact that it's usually just an increment is convention. Or would the perfectly legal (with a suitable backend) i.deleteLastNode() as the final condition also constitute an "increment"?
  • em (unregistered) in reply to DZ-Jay
    DZ-Jay:
    I disagree with you.  I think that "for (int i=1;i<=4;i++)" is pretty clear -- but it is a *generic* loop construct, which is what it was designed to be.  It specifies:

        Variable initialization (i.e. which value to start with)     Exit condition (i.e. which value to end with)     Increment (i.e. how much to increment the variable after each iteration).

    No, no, no. That's far from generic. It has a hell of a lot of baggage in it. In particular, it couples too tightly the iteration logic with the things to be done in each iteration.

    What do I regard as a generic iteration mechanism? Well, iteration involves (a) a set of things to be iterated over, (b) an order in which the iteration happens, (c) the thing that is done in each iteration, and (d) the way the iterations contribute to the overall result. The set of things may be numbers, or it may be nodes of a tree. The order may be the normal integer succession, or it may be the preorder of the nodes of a tree. The thing to be done varies endlessly; that's why we have loop bodies, after all. The ways the iterations contribute to the result are many: sometime we want to produce another similar collection of elements, where each element in the result is "mapped" to a result indpendently; other times we want to collapse (or "fold") a collection down to some result value which depends on all of the elements.

    Languages that provide what I call a proper abstraction here separate all of these things. Instead of writing a loop to sum the elements of an array or to multiply each by a constant, you fold a sequence with the plus operator, or map a constant multiplication function over it. Have to do the same over a tree instead of an array? No problem, just say what order you want (preorder, postorder, inorder).

  • Z (unregistered) in reply to bp
    Anonymous:
    Anonymous:

    Well, the WTF does have one tiny advantage over the usual way (not that it justifies it [+o(]).

    The ForTo enumerator does not have the vulnerability that an accidental i-- or i = something in the body can cause an infinite loop. Yeah, I know I need to get past my hangup of preferring definite iteration (guaranteed to terminate) over indefinite iteration but I still havent registered for the 12 step program yet... [*-)]



    You mean you wouldn't catch that running your unit tests?
    umm... you are writing unit tests right?


    I've always wondered why unit test-evangelists fail to realise that they can't catch every bug ("testing can only show the prescence of bugs, not their absence", Dijkstra). Furthermore, it's always better to catch bugs by design than by testing, its faster, easier, and cheaper. Plus, the result will be more intelligible.

    In the above example: the i=something could be some complex assignement (instead of a complex test) that would only lead to an infinite loop for very special cases of something.
  • J Drakes (unregistered)

    I can see from many of the posts that there is a widespread belief that if it is not part of the language, then you shouldn't do it, you should change language.

    Leaving aside the fact that in many projects this would not be feasible for a number of reasons, am I the only one here to think that if you can make the language more readable and usable then you should do it? 

    On the other side I see appreciation for the idioms of the language, which are seen as being superior to any possible change.  Unfortunately these idioms -IMO- while powerful, often make for less readable code.

    What do you guys think? Which side are you on? and why?

  • (cs) in reply to J Drakes

    I don't think (and most agree here if I'm right) that the code doesn't offer any value over the "for (int i ... i++)" syntax, and in it's current form shouldn't be used in production code to prevent, but it's a nice and simple example on how to implement IEnumerable, and definately not a WTF.

  • (cs) in reply to wtijsma

    BTW, WTF is there an edit button above my posts if I can't edit it because it has to be edited within 5 ms after posting?

  • (cs)

    This isn't a real WTF. The biggest wtf with this is actually the naming. ForTo doesn't specify the functionality. Range is a much better name. Also, this code becomes bloated because it isn't using C# 2.0. Here is the same functionality in C# 2.0.

    public class Series
    {
        public static IEnumerable<int> Range(int start, int stop)
        {
          return Range(start, stop, 1);
        }
    
        public static IEnumerable<int> Range(int start, int stop, int step)
        {
          for (int i = start; i <= stop; i += step)
            yield return i;
        }
    }
    ..
    foreach(int i in Series.Range(9,18,3))
    ..
    

    Much more readable, and less error prone. The speed is about 1/10 of an ordinary for loop, which isn't the best but unless speed is really critical it shouldn't matter.

    Using c# 2.0 I have come to rely more on iterators and the yield syntax. They can seriously improve code readability and are easy to write correctly. Personally I prefer using the for loop, but I have no problem at all reading the foreach variant and people calling this a wtf are seriously shortminded. As some people have shown, doing this bears a striking resemblance to Python syntax and several other languages have similar constructs.

    The real wtf in pascal.h is that keywords are redefined which doesn't actually add anything useful. Syntax sugar must do more than change words to be useful. A Range iterator provides functionality in that it hides comparisons as well as increments. That is useful syntactic sugar unlike replacing { with begin.

  • (cs) in reply to wildclaw

    If anything is wtf, it is this forums preview. It should be removed since it doesn't actually show the previewed message. Ok, second try, code only

    public class Series { public static IEnumerable<int> Range(int start, int stop) { return Range(start, stop, 1); }

    public static IEnumerable&lt;int&gt; Range(int start, int stop, int step)
    {
      for (int i = start; i &lt;= stop; i += step)
        yield return i;
    }
    

    } .. foreach(int i in Series.Range(9,18,3)) ..

  • (cs)

    OK.

    I can't comment any further on the code. However, why are people calling it C-Pound?

    It's C Sharp.  C#.

    C Pound would be C£.

    Please remember that not everyone lives in the USA.

  • (cs) in reply to jzlondon
    jzlondon:
    I can't comment any further on the code. However, why are people calling it C-Pound?

    It's C Sharp.  C#.

    Yes, as the interviewer did try to correct by subtle means....

    http://www.thedailywtf.com/forums/25129/ShowPost.aspx

  • (cs) in reply to jzlondon
    jzlondon:

    OK.

    I can't comment any further on the code. However, why are people calling it C-Pound?

    It's C Sharp.  C#.

    C Pound would be C£.

    Please remember that not everyone lives in the USA.



    I think it would be best that you remember not everyone lives in a country where the currency is based on the british pound.  Anywhere else in the world, and I'm reasonably certain that even in jolly old England, there is a # on your telephones, which is called the pound sign.

    As for calling it C-Pound, as has been explained elsewhere in this WTF, it's a stab at hackjob programmers who don't know the proper name for the language, although as has also been mentioned, I move that we instead call it D-flat.
  • AJR (unregistered) in reply to JThelen
    JThelen:


    I think it would be best that you remember not everyone lives in a country where the currency is based on the british pound.  Anywhere else in the world, and I'm reasonably certain that even in jolly old England, there is a # on your telephones, which is called the pound sign.


    Yes, there is a # sign on UK phones, but nobody here calls in a "pound sign".  Most people call it a "hash" (although for some reason BT's recorded messages call it "the square key.")
    To allow everyone to be equally confused, I propose that C# be read as "C octothorpe" :-P
  • (cs) in reply to DZ-Jay
    DZ-Jay:
    Anonymous:

    The intent is not completely evil, as it allows you to define range objects (although the author decides to obscure readibility with a redundant new ForTo syntax).  providing a function building the object could make it nicer:

    <font color="#848284">foreach (int i in range(1,4))</font>

    btw, I don't agree that

    <font color="#848284">for (int i=1;i<=4;i++) </font>

    is inherently clearer than the above. quite the opposite.

    Look at them and you'll realize that we think it's clearer only because of habit.

    The first goes straight to the intent, without getting us into concepts such as <= and ++, that are really irrelevant to the underlying intention of moving from 1 to 4.  The C-like syntax confuses the what with the how.



    I disagree with you.  I think that

    <font color="#848284">for (int i=1;i<=4;i++)

    </font>is pretty clear -- but it is a *generic* loop construct, which is what it was designed to be.


    Recursion is a pretty damn general 'loop construct' too, rather more general than for() is in fact, yet even a rabid Schemer like me would be hard put to argue that recursion is clearer than a specialized iterative construct in all cases (in Scheme. it usually is, as well as in the majority of FP and Logic languages, but those languages were designed for clear expression of recursive idioms). As you point out yourself, certain constructs are common enough that a specialized construct is justified; indeed, if you are familiar you with such reducto ad absurdum languages as Unlambda or OISC, then you know that every construct is a special-purpose one - there is always some way of deriving any construct from some other primitive, and for any given primitive there are other equally primitive constructs which it can be duplicated with. In any practical language, you have make some arbitrary choices as to which primitives to support (though as you can guess, I personally prefer languages where it is possible to define first-class user syntax constructs with a minimum of fuss).

    Where was I going with this, anyway? Oh, never mind. Consider it just something to reflect upon in an idle moment later.
  • (cs) in reply to icelava

    Ah... get it now!  What a stunning candidate.

    I spent some time in America last year and you can imagine my surprise the first time I heard an automated switchboard ask callers to press the "pound key".  WTF? 

    I had no idea until that point that you guys called the # (hash) symbol "pound".  Strange - I wonder how it came about. 

    It's a bit like calling the @ symbol "dollar".

     

  • Anonymous (unregistered) in reply to mugs
    Anonymous:

    Anonymous:
    Am I the only one (maybe missing prior post) that sees this flaw with the for (;;) construct:

    for (int I = 0; I < StupidSlowUpperLimit(); ++I) {
        // Stuff
    };

    At least in Pascal

    FOR I := 0 TO StupidSlowUpperLimit() DO BEGIN
    END;

    you are guaranteed the limits are only evaluated once on entry. The same applies to the code in this post (although that is its only redeeming feature).

    You could just assign StupidSlowUpperLimit() to a variable and use that variable as the upper limit of the loop to accomplish the same thing...



    What C and C-like languages need is a proper "loop <statement>" statement like (?Pascal) Modula-2's LOOP ... END; and then use break to leave the loop whenever we need to. I think "foreach <ident>in <generator>..." is the way forward. The for (;;) construct is simply an artefact of when computers were slow, compilers were dumb and C was just a refined version of a macro assembler.
    </generator></ident></statement>

    If you want to do that, just use while(true){} and then break; whenever you decide you want to break out of the loop.



    Using while(true){} assumes the compiler will optimize out the redundant check at each step, and assumptions about optimization strategies are bad. In fact you can use for(;;) {} instead. Oh, and don't forget:

    start:
        if (condition) goto end;
        goto start;
    end:
    0;

    We need the 0 here since C does not allow a label by itself at the end of a block, (well GCC anyway). Let's hope the compiler optimizes it out, right?

    Also assigning StupidSlowUpperLimit() to a variable forces it to be stored in a variable somewhere, ruining optimization strategies, as well as the automatic decision regarding what type of variable to store the limit in. Finally it is still a means of emulating a language feature that C is missing.

    On the otherhand, to have a for(;;) {} in a language like Modula-2

    for (<init>; <condition>; <post>) <body>;

    becomes

    <init>;
    LOOP IF NOT <condition> THEN EXIT END;
        <body>;
        <post>;
    END;

    And don't say anything about the scope of variables in the <init> code since it isn't really standardized properly anyway. Nothing that a VAR BEGIN END won't solve anyway.

    I have always disliked the C syntax, and think is extremely stupid (and typical of the computer industry) to continue to use it in languages like Java and C#.
  • (cs) in reply to jzlondon
    jzlondon:
    I had no idea until that point that you guys called the # (hash) symbol "pound".  Strange - I wonder how it came about. 

    It's a bit like calling the @ symbol "dollar".

    Apparently, it was once popular as an abbrevation for "pound" (as in weight)

    e.g  " 5 # @ .30/#...... $1.50"

    However, I believe this usage peaked in the 19th Century (when everything was hand written, and therefore you looked for as many abbreviations as possible)

Leave a comment on “Why C-Pound Needs Macros”

Log In or post as a guest

Replying to comment #:

« Return to Article