C++0x



  • C++ is already a horribly complex language, I took a look at the proposed features of C++0x last night, and I have to say, they are creating a language that no one will be able to fully understand.

    Take for example, user defined literals:

    OutputType operator"Suffix"(const char literal_string);

    OutputType someVariable = 1234Suffix;

     No, I don't see that getting abused :(

     Or how about this, meta programming through recursion:

    template< int B, int N >
    struct Pow
    {
    // recursive call and recombination.
    enum{ value = B
    Pow< B, N-1 >::value } ;
    }
     ;template< int B > struct Pow< B, 0 >  // ''N == 0'' condition of termination.
    {
    enum{ value = 1 } ;
    } ;
    int quartic_of_three = Pow< 3, 4 >::value ;

     I don't know how anyone will be able to master this language, the entire thing is just nuts.



  •  Not sure it's as bad as all that - it has some useful ideas.



  • C++ is already a language no-one can fully understand. If you have any doubt of that, read up on the pain Herb Sutter went through with exceptions.

    Recursive template metaprogramming has been around for ages. Even before you had the support within C++ compilers to do that kind of stuff "properly" with templates, you still had people doing Towers of Hanoi purely using the C preprocessor via #define's.

    I agree there's definitely a WTF in asking who would bother using template recursion when normal function recursion would be just fine but that's the programmer being a retard rather than the fault of C++. Template specialisation has a lot of legitimate uses, although I would agree that a Fibonacci sequence generator (etc.) probably isn't one of them. 



  • Ewwwww. Just when I thought C++ syntax couldn't get any more ghastly.



  • Many of the new features in C++0x are things that you would already expect C++ to be able to do at some level, but then it turns out it can't and you're screwed.  So you kludge up some horrible hack to fill in the gap.  Used judiciously the new standard could be a net boon to clarity and simplicity in practice, I think.



  • @JukeboxJim said:

    I agree there's definitely a WTF in asking who would bother using template recursion when normal function recursion would be just fine but that's the programmer being a retard rather than the fault of C++. Template specialisation has a lot of legitimate uses, although I would agree that a Fibonacci sequence generator (etc.) probably isn't one of them.
     

    It depends on where you want the calculation run -- with regular functions, it's a run-time, with template recursion it's a compile-time.  One uses the programmer's time once (and gets reduced to a constant generally), the other uses the user's time every time it runs

    It's not a WTF at all unless you use it wrong.  A Fibonacci number generator is useful in template-recursive form if you need to be able to change which number you're getting (at compile-time), and you don't want to calculate it yourself, but you don't want to waste the user's time.

    Something tells me I didn't make much sense there but since my brain is exploding in frustration at my manager right now I'm not going to try to reword it.  Read it as I meant it, not as I wrote it.



  • I guess the logical end will come when it becomes as much WTF as Algol-68

     



  • @mfah said:

    Ewwwww. Just when I thought C++ syntax couldn't get any more ghastly.
     

    While I won't claim that C++ is the easiest to understand language out there, I never heard anybody claim that C++ syntax was "ghastly" or anything negative.  Where is all of this negativity coming from?

    With regards to these new specs... I really wonder sometimes why programmers think that just about anything can be solved by templates and such. 



  • @Jonathan Holland said:

    C++ is already a horribly complex language, I took a look at the proposed features of C++0x last night, and I have to say, they are creating a language that no one will be able to fully understand.

    ...snip...

     I don't know how anyone will be able to master this language, the entire thing is just nuts.

     

    I fail to see, however, why you think it is necessary for one person to understand all the details of the language. You can be fairly proficient in it without ever touching things like template metaprogramming (which is something that already exists in C++, and not nothing that is going to be added just now).



  • @WeatherGod said:

    @mfah said:

    Ewwwww. Just when I thought C++ syntax couldn't get any more ghastly.
     

    While I won't claim that C++ is the easiest to understand language out there, I never heard anybody claim that C++ syntax was "ghastly" or anything negative.  Where is all of this negativity coming from?

    With regards to these new specs... I really wonder sometimes why programmers think that just about anything can be solved by templates and such. 


    Admittedly it's a purely personal opinion, but things like re-using the bit-shift operators for stream IO (I know where this comes from, but that doesn't mean I have to like it), and the whole template syntax, just make me want to search for a solid object to cling to.



  • @fist-poster said:

    I fail to see, however, why you think it is necessary for one person to understand all the details of the language. You can be fairly proficient in it without ever touching things like template metaprogramming (which is something that already exists in C++, and not nothing that is going to be added just now).

     

    You can be "fairly" proficient in Python by stuffing everything in Java-style class structures and never using a list comprehension, but you'd be an idiot if you did.  Understanding the language means taking full advantage of the facilities it provides.  Nearly all of the features of a language can be utilized in making more correct/fast/small/elegant code.

    C++ makes it much impossible for one person to write the best code possible at any given time. 

    I'm not talking about libraries here.  I'm talking only about syntax.



  • @WeatherGod said:

    @mfah said:

    Ewwwww. Just when I thought C++ syntax couldn't get any more ghastly.
     

    While I won't claim that C++ is the easiest to understand language out there, I never heard anybody claim that C++ syntax was "ghastly" or anything negative.  Where is all of this negativity coming from?

    You'll find it a pretty common opinon (or even a truism) in hacker circles that C++ syntax is big, ugly, overcomplicated, and impossible to fit in ones head.



  • @mfah said:

     Admittedly it's a purely personal opinion, but things like re-using the bit-shift operators for stream IO (I know where this comes from, but that doesn't mean I have to like it), and the whole template syntax, just make me want to search for a solid object to cling to.

     

    I quite like that, since bitshifting is used so rarely, it could be argued (and is in some C++ books) that the operators are in fact I/O operators, with the bitshifting ability only there for compatabiliy with old C code.

    @C++ said:

    cout << "Literal" << someStdString << someInt << someCustomClass;

    Is certianly easier to me than

    @Some unnamed 'modern' language said:

    Console.Write("Literal" + someString + someInt.ToString() + someCustomClass.ToString())

     

    Plus with the Boost libraries, you can do all sorts of cool things:

    @C++ with Boost said:

    int i=lexical_cast<int>("12345");

    BOOST_FOREACH(int i, someVectorOfInts){ ... } //often #defined foreach

    shared_ptr<int> p(new int(255)); //Guaranteed to be delete'd as soon as the last reference is gone.

    myfunction(_foo=10, _bar=7);

    for_each(a.begin(), a.end(), cout << _1 << endl);

    etc, etc.

    (Note that most of the additions to the standard library proposed for C++ 0x are taken from boost.) 

     



  • Interestingly enough, I use bitshifts fairly extensively in C. There's always one, isn't there?



  • @mfah said:

    Interestingly enough, I use bitshifts fairly extensively in C. There's always one, isn't there?
     

    Same here. Anyone doing low level programming is going to use them a lot. 

    There's an excellent resource demonstrating the true insanity of the C++ language: http://yosefk.com/c++fqa/

    One interesting fact about the grammar is that it can't be easily  defined. It's no wonder everybody has problems remembering every case.

    @C++ FQA said:

    Outstandingly complicated grammar

    "Outstandingly" should be interpreted literally, because all popular languages have context-free
    (or "nearly" context-free) grammars, while C++ has undecidable grammar.
    If you like compilers
    and parsers, you probably know what this means. If you're not into this kind of thing, there's a
    simple example showing the problem with parsing C++: is AA BB(CC); an object definition
    or a function declaration? It turns out that the answer depends heavily on the code before the statement -
    the "context". This shows (on an intuitive level) that the C++ grammar is quite context-sensitive.

     



  •  In my opinion, templates are a solution to a problem best solved by changing languages.



  • Bah, if you don't like C++ or think it's too complicated, you're just a n00b

    ;-P 

     

    Every managed language out there is a non-solution to the problem of developers simply not learning how to code properly in the first place. 



  • @Jonathan Holland said:

    C++ is already a horribly complex language, I took a look at the proposed features of C++0x last night, and I have to say, they are creating a language that no one will be able to fully understand.

    Take for example, user defined literals:

    OutputType operator"Suffix"(const char *literal_string);

    OutputType someVariable = 1234Suffix;

     No, I don't see that getting abused :(

     

    Actually, this seems like a useful feature to me (assuming I understand it correctly, since all I know about C++0x is from your post ;-)

    Date myBirthdate = 11.4.1970date;

    Recangle tinyScreen = 800x600rectangle; 

     

    Edit: could the following be made?

    Complex x = 10.3+6.9i;

     



  • @mallard said:

    @C++ said:

    cout << "Literal" << someStdString << someInt << someCustomClass;

     

    Funny, I find

    @Std C said:

    printf("Literal %-5d: %6.2f\n", i, f(i));

    much easier than

    @C++ said:

    std::cout << "Literal";

    std::cout.width(5);

    std::cout << std::left << i << std::right;

    std::cout.precision(6);

    std::cout.width(0); 

    std::cout << std::fixed <<  f(i) << std::endl;

     

    In fact, the second example probably doesn't even do what I wanted - I don't like the stuff, and I don't use it. It's just too wordy, and you give up control over what gets printed (hidden states in the stream object). I'll use a good old FILE* and fread(buf, sizeof(int), BUFSIZE, f) any day. I'm not saying I want to use plain C - objects are good and useful - but many aspects of C++ are too clunky and wordy for me. Or maybe I just don't see the beauty of them, I don't know.



  • @alegr said:

    I guess the logical end will come when it becomes as much WTF as Algol-68

    Why do you think A68 is a WTF? It's a great language! C++ with its multiple inheritance, that's a WTF already. 



  • @boh said:

    Funny, I find

    @Std C said:

    printf("Literal %-5d: %6.2f\n", i, f(i));

    much easier than

    I use printf (and variants) over the iostream stuff wherever possible as well. I do have a type-safe 'printf-like' library I use and I think that would be a good addition to C++ rather than some of the obscure stuff.

    iostream I/O just cannot be internationalised with any level of ease, whereas printf (or, even better, a 'positional' printf like the Windows 'FormatMessage') can be internationalised much more easily.



  • @boh said:

    Funny, I find

    @Std C said:

    printf("Literal %-5d: %6.2f\n", i, f(i));

    much easier than

    @C++ said:

    std::cout << "Literal";

    std::cout.width(5);

    std::cout << std::left << i << std::right;

    std::cout.precision(6);

    std::cout.width(0); 

    std::cout << std::fixed <<  f(i) << std::endl;

     

    In fact, the second example probably doesn't even do what I wanted - I don't like the stuff, and I don't use it. It's just too wordy, and you give up control over what gets printed (hidden states in the stream object). I'll use a good old FILE* and fread(buf, sizeof(int), BUFSIZE, f) any day. I'm not saying I want to use plain C - objects are good and useful - but many aspects of C++ are too clunky and wordy for me. Or maybe I just don't see the beauty of them, I don't know.

     

    Then boost::format provides the best of both worlds:

    @C++ with Boost said:

    cout << "Literal " << format("%-5d: %6.2f) % i % f(i) << endl;

    And it's type-safe too... In fact, if you are using C++ with modern libraries (boost, gtkmm, etc) then you should never have to write non-type-safe code, nor touch a raw pointer.



  • Ok, but how do you pronounce "C++0x" ?



  • @djork said:

    @fist-poster said:

    I fail to see, however, why you think it is necessary for one person to understand all the details of the language. You can be fairly proficient in it without ever touching things like template metaprogramming (which is something that already exists in C++, and not nothing that is going to be added just now).

     

    You can be "fairly" proficient in Python by stuffing everything in Java-style class structures and never using a list comprehension, but you'd be an idiot if you did.  Understanding the language means taking full advantage of the facilities it provides.  Nearly all of the features of a language can be utilized in making more correct/fast/small/elegant code.

    C++ makes it much impossible for one person to write the best code possible at any given time. 

    I'm not talking about libraries here.  I'm talking only about syntax.

     

    I feel you are comparing apples and oranges, though. List comprehension is part of the Python syntax (if I'm not mistaken), template metaprogramming is a specific coding technique (I'm not even sure if templates were designed in C++ with metaprogramming in mind in the first place, or was this technique discovered later). Enums as a syntax feature are not complicated, templates (although there are some obscure corners) - at least as far as the code example is concerned - ain't that hard either. The hard part is putting 1 and 1 together and realising you can force the compiler do something at compile-time this way.

    I mean, you may know everything there is to know about the syntax of bitwise operators, and it may still not click that this way you could represent several boolean states in a single variable.

    I'm also not sure whether you can even always achieve correctness, speed, smallness and elegance at the same time. But this probably also depends on what is considered elegant in one or another language. If I nest several list comprehensions and do stuff on a single line that would take a page in C++, would that be considered elegant by Python programmers?



  • @boh said:

    Funny, I find

    @Std C said:

    printf("Literal %-5d: %6.2f\n", i, f(i));

    much easier than

    @C++ said:

    std::cout << "Literal";

    std::cout.width(5);

    std::cout << std::left << i << std::right;

    std::cout.precision(6);

    std::cout.width(0); 

    std::cout << std::fixed <<  f(i) << std::endl;

     

    In fact, the second example probably doesn't even do what I wanted - I don't like the stuff, and I don't use it. It's just too wordy, and you give up control over what gets printed (hidden states in the stream object). I'll use a good old FILE* and fread(buf, sizeof(int), BUFSIZE, f) any day. I'm not saying I want to use plain C - objects are good and useful - but many aspects of C++ are too clunky and wordy for me. Or maybe I just don't see the beauty of them, I don't know.

     

    That's great and all, but if you're unfamiliar with printf's formatting syntax and you just do a quick glance at the code, you know exactly what the C++ snippet is doing, but you have to go look up what the printf statement does.

    Honestly, in this case, I think people are more comfortable with what they learned first - I learned C++ first, so I'm more comfortable with iostream and friends, whereas people I know who learned C first are more comfortable with printf and friends.  Neither is necessarily better than the other (though iostreams can be slower in some cases), they're just different ways of going about the same thing. 



  • @tray said:

    Ok, but how do you pronounce "C++0x" ?

    Assuming you're joking, I'm answering anyway:

    "See Plus Plus Oh Eks "



  • @Nandurius said:

    One interesting fact about the grammar is that it can't be easily  defined. It's no wonder everybody has problems remembering every case.

    @C++ FQA said:

    Outstandingly complicated grammar

    "Outstandingly" should be interpreted literally, because all popular languages have context-free
    (or "nearly" context-free) grammars, while C++ has undecidable grammar.
    If you like compilers
    and parsers, you probably know what this means. If you're not into this kind of thing, there's a
    simple example showing the problem with parsing C++: is AA BB(CC); an object definition
    or a function declaration? It turns out that the answer depends heavily on the code before the statement -
    the "context". This shows (on an intuitive level) that the C++ grammar is quite context-sensitive.

     

    So C++ is unpopular?  Gee, we should go tell all those game studios who sell millions of copies that if they used Java they could sell millions more!  Don't tell me that quote doesn't say C++ is unpopular, because it does:  All X are like this, but Y is not like this (implication being that Y is not among X).

    Yes, some of C++ is context-sensitive, but that's a consequence of allowing user-defined objects, not a consequence of complexity.  I don't know of a completely context-free language.  C++'s grammar is not undecidable - the example of AA BB(CC) is misleading, since the two cases are quite simple:

    1) If CC is a list of variable declarations (e.g., "int x, int y, int z") then it must be a function declaration.

    2) If CC is a list of values (e.g., "5, s, t()" where s is a preexisting int and t is a function returning an int) then it must be a class object instantiation.

    There is nothing "undecidable" about that.  Saying it "depends heavily on the code before the statement" is outright false, since determining whether it's an instantiation or function declaration does not require knowledge about any other part of the code.  (Yes, you need to know what a Foobar is to instantiate one, but you don't need to know that to determine wehther it's an instantiation or a function declaration.)

    You cannot forward-declare a function by saying "int foo(3, x, y);" nor can you instantiate a class object with "Foobar foo(int x, int y, int z);".  The second one would be interpreted as a function declaration where the function returns an object of type Foobar.

    It would seem that whoever wrote that FQA is far from being an expert in language design as they seem to imply.  Reading through a few of their examples, I find a striking simliarity with rants bashing various churches for no better reason than to bash; they word things their own way to make the object of their rant seem bad.  (For example, they imply that C++ is unpopular even though that is clearly not the case.)  Sure, C++ isn't perfect, but neither is C, nor Java, nor anything.  It is not the right tool for every job, but there is no one tool that works for every job.  The FQA authors clearly have a distaste for C++ and they did not take the time to understand C++ enough to be able to understand what they're writing about.

    To make my point clear, I have just shown that determining whether a
    statement of the form AA BB(CC) is a function declaration or an object
    instantiation is a context-free process, therefore the author of that
    FQA question is either stupid, lying, or not trying to understand what he's
    ranting about.  I have sent an e-mail to the FQA author correcting the quotation in question; if he ignores it we'll know for sure whether he cares about the truth or whether he simply wants to rant.

    For what it's worth I don't consider C++ too complex; templates are not particularly difficult to understand (even template metaprogramming), the syntax is just as easy as C, and I personally find development time faster in C++ than Java (and C#, except for GUIs).  These are my own opinions and should be treated as such - no one flame me with a "C++ DROOLS, JAVA RULES" or whatever.

     

    And I had to laugh at this quote from the FQA:

    And the best part is that C++ devotees dare to refer to the C features as
    evil, and frequently will actually resort to finger pointing and name calling when someone uses them in C++ code

    because he does the exact same thing (that is, finger pointing and name calling). 



  • To Heron: thanks for the illuminating comment.  I was just looking at that FQA page and I couldn't follow the guy's logic regarding his complaint about AA BB(CC).  In the end, I could only conclude that he was referring to some obscure practices in C++ that I was not aware of.  Now, I can see that he was restraining the reader's perception into thinking that these sort of 'problems' always occur in C++ programing, when they never occur in practice.

    If anyone can find a better resource regarding the "weirdness" of C++ syntax, I would be more than willing to read it, but this guy is not sane. 



  • I wouldn't say that C++ is not wierd, but I use it everyday along with C#, and I enjoy using both. Both have their strengths and weaknesses, and Heron was correct by saying that there is not one tool that is right for every job. If you're doing embedded systems, gaming, or stuff like that, C++ is the place to be if you want the speed. It might give you ways to shoot yourself in the foot, but thats our own fault if we don't use the tool correctly. Just like if you don't use a chainsaw correctly, it could mean the difference between sitting by the fire with some hot chocolate vs. spending the night in the hospital with an amputated leg.



  •  The FAQ guy probably got the idea from this "confusing" thing:

    X a; 

    and

    X a();

    The second one will be interpreted as a function prototype, the first one declares an object of type X using the default constructor. (This is something you have to know, but it should take making this mistake once and learning it forever.

    However, for some reason he concludes from this that it will be even worse if there is something between the brackets. This doesn't make any sense, if there is something between the brackets, there will be no ambiguity.

    From a brief look, the criticism looks rather incompetent. For example this pearl:
    "Here's a common "design pattern" in C++ code. You have a huge class..." following some criticism how this big class makes life hard. Doh!



  •  Heron, I would never claim that C++ is unpopular or useless.. far from it. I've enjoyed the rant that is the FQA immensely though, and I do think that there's a lot of truth in what he's pointing out, even if it's done in a very emotional/inflamatory way.

     As for the language grammars, the grammar to the Java language is defined in BNF and is context free:  http://java.sun.com/docs/books/jls/third_edition/html/syntax.html#18.1

    What I've been able to find on the C++ language is far from encouraging: http://compilers.iecc.com/comparch/article/01-08-043 It's a very interesting discussion though.

     



  • @Heron said:

    Yes, some of C++ is context-sensitive, but that's a consequence of allowing user-defined objects, not a consequence of complexity.  I don't know of a completely context-free language.  C++'s grammar is not undecidable

    Provided the compiler does not enforce a maximum depth limit to recursive templates, the compilation of a given C++ program is equivalent to the halting problem, and thus undecidable.

    - the example of AA BB(CC) is misleading, since the two cases are quite simple:

    1) If CC is a list of variable declarations (e.g., "int x, int y, int z") then it must be a function declaration.

    Function prototypes need not include names for the parameters.  int foo (int, int, int) is a perfectly valid function prototype.

    2) If CC is a list of values (e.g., "5, s, t()" where s is a preexisting int and t is a function returning an int) then it must be a class object instantiation.

    Yes, but what if you have this:

    rectangle foo(square);

    It could either be a function prototype (prototypes don't actually require variable names, just types), or it could be a variable declaration.  There's no way of knowing without determining whether rectangle is a variable or type.

    There is nothing "undecidable" about that.

    Really?  What if rectangle is a recursive template definition?  Now
    the code is not only context-sensitive, but completely undecidable.

    Saying it "depends heavily on the code before the statement" is outright false, since determining whether it's an instantiation or function declaration does not require knowledge about any other part of the code.  (Yes, you need to know what a Foobar is to instantiate one, but you don't need to know that to determine wehther it's an instantiation or a function declaration.)

    I've just proven this to be false. You must know whether or not square is a type or a variable.

    You cannot forward-declare a function by saying "int foo(3, x, y);" nor can you instantiate a class object with "Foobar foo(int x, int y, int z);".  The second one would be interpreted as a function declaration where the function returns an object of type Foobar.

    I can forward-declare a function by saying Foobar foo (a, b, C).  I can also instantiate a class object by saying Foobar foo (a, b, C).  This should be pretty clear by now.

    It would seem that whoever wrote that FQA is far from being an expert in language design as they seem to imply.  Reading through a few of their examples, I find a striking simliarity with rants bashing various churches for no better reason than to bash; they word things their own way to make the object of their rant seem bad.  (For example, they imply that C++ is unpopular even though that is clearly not the case.)

    Agreed.  They bash C++ for things that many major languages use, and they do so in such a way as to imply that C++ is bizarre for doing things this way.

    Sure, C++ isn't perfect, but neither is C, nor Java, nor anything.  It is not the right tool for every job, but there is no one tool that works for every job.  The FQA authors clearly have a distaste for C++ and they did not take the time to understand C++ enough to be able to understand what they're writing about.
      Neither did you, if you didn't know that int foo (int, int, int) is a valid function definition.

    To make my point clear, I have just shown that determining whether a
    statement of the form AA BB(CC) is a function declaration or an object
    instantiation is a context-free process,
      Nope.

    therefore the author of that
    FQA question is either stupid, lying, or not trying to understand what he's
    ranting about.
      "Hello, Mr. Kettle?  This is Mr. Pot.  I just thought you should know that you're black."

    I have sent an e-mail to the FQA author correcting the quotation in question; if he ignores it we'll know for sure whether he cares about the truth or whether he simply wants to rant.
      If he ignores it, it's probably because you're talking about things you don't know.

    For what it's worth I don't consider C++ too complex; templates are not particularly difficult to understand (even template metaprogramming), the syntax is just as easy as C,
      I believe that's what we call "damning with faint praise."

    and I personally find development time faster in C++ than Java (and C#, except for GUIs).  These are my own opinions and should be treated as such - no one flame me with a "C++ DROOLS, JAVA RULES" or whatever.
      Agreed.  One could find problems with any language (I mean, have you seen LISP?  Parentheses everywhere!).

    And I had to laugh at this quote from the FQA:

    And the best part is that C++ devotees dare to refer to the C features as
    evil, and frequently will actually resort to finger pointing and name calling when someone uses them in C++ code

    because he does the exact same thing (that is, finger pointing and name calling).

    I agree that the FQA gets quite childish at times.  But give the author some credit, C did do a lot of things right.  And there is a large portion of the C++ world who look down their noses at anything from C.  Hell, I was one back before I ever worked in C.



  • @tray said:

    Ok, but how do you pronounce "C++0x" ?

    You have to use gutturals. It goes CHHHHHHHAWKKKKHHHH, and then you spit.



  • @CDarklock said:

    @tray said:

    Ok, but how do you pronounce "C++0x" ?

    You have to use gutturals. It goes CHHHHHHHAWKKKKHHHH, and then you spit.

     

    I have to say.... that made my night :)

     

    And to bstorer, you make several good points... But it's more of a theoretical problem than a practical problem, and it's just as much of a problem in C as it is in C++.  In practice, though, the compiler knows whether a given symbol is defined until "now" when it comes to a line of code (it keeps a lookup table), and it knows whether it's a typename or a variable.  So while technically it is true that you could create an example where a line of code would be undecidable (i.e. using a template metaprogram), using a typename in a parameter list isn't one of those cases in practice.



  • @Heron said:

    if you're unfamiliar with printf's formatting syntax

    Hold on - it's a long time since I was in college, but printf is still the first thing you learn after "main", isn't it?



  • @mfah said:

    @Heron said:
    if you're unfamiliar with printf's formatting syntax

    Hold on - it's a long time since I was in college, but printf is still the first thing you learn after "main", isn't it?
     

    Yeah, things have changed.  Last year I was a TA for a computing for meteorologists class, which had a requirement of a C++ or Java or VisuaBasic class (thats another WTF).  None of the C++ students ever heard of printf().  It gets annoying to see them use if-statements in Perl to pad a zero onto the left of a single digit number. 



  • @mfah said:

    Hold on - it's a long time since I was in college, but printf is still the first thing you learn after "main", isn't it?

    I learned C++ on my own.  The programming class I took in high school taught C++ (nothing I didn't know already).   When I got to college the entry-level classes used Java.  The first time I used C was in an electrical engineering class, and all I did was look up two or three printf flags.  My current job is a C++ application that came from old C code, so it has calls to printf scattered around on occasion, but I just look up the flags when I need them... printf isn't as universal as it once was ;)



  • @Heron said:

    printf isn't as universal as it once was ;)
    Python and PHP both have implementations of printf (python's is a language feature, which is awkward at first). I think perl has printf as well, although I'm not too sure about the languages that are popular outside of FOSS, mind you with FOSS' love of C I'm not surprised that the P3 have an implementation of printf. Also for the record printf is generally more legible than cout for advanced formatting, especially when you have no idea how the type is formatted.



  • @Lingerance said:

    @Heron said:
    printf isn't as universal as it once was ;)
    Python and PHP both have implementations of printf (python's is a language feature, which is awkward at first). I think perl has printf as well, although I'm not too sure about the languages that are popular outside of FOSS, mind you with FOSS' love of C I'm not surprised that the P3 have an implementation of printf. Also for the record printf is generally more legible than cout for advanced formatting, especially when you have no idea how the type is formatted.
     

    Is it me, or does the C++ cout thing fall flat on it's arse the moment you want to localize your application ?

    At least with the printf method, you have a better chance by having the format string come from a resource file (although not 100% either, since the order of the placeholders may end up being different too if you have more than one in your format).

    With cout, you are shit out of luck since the order of the output is even more ingrained in the code*.

    * Disclaimer: I really don't know much about C++, except for the bits that are C.

     



  • @Heron said:

    And to bstorer, you make several good points... But it's more of a theoretical problem than a practical problem, and it's just as much of a problem in C as it is in C++.  In practice, though, the compiler knows whether a given symbol is defined until "now" when it comes to a line of code (it keeps a lookup table), and it knows whether it's a typename or a variable.  So while technically it is true that you could create an example where a line of code would be undecidable (i.e. using a template metaprogram), using a typename in a parameter list isn't one of those cases in practice.

     

    Wrong again.  Consider the following, where Number is a class with a constructor taking an int:

    template <typename T>
    struct RECURSE
    {
    typedef typename RECURSE< RECURSE<T> >::BAD BAD;
    };

    typedef RECURSE<int> FOO;
    Number Bar (FOO::BAD);
    and
    struct FOO
    {
    const static int BAD = 5;
    };

    ...

    Number Bar (FOO::BAD);

    The first one will recurse forever on compilation. The second works just fine. Wicked, eh?



  • @bstorer said:

    @Heron said:

    And to bstorer, you make several good points... But it's more of a theoretical problem than a practical problem, and it's just as much of a problem in C as it is in C++.  In practice, though, the compiler knows whether a given symbol is defined until "now" when it comes to a line of code (it keeps a lookup table), and it knows whether it's a typename or a variable.  So while technically it is true that you could create an example where a line of code would be undecidable (i.e. using a template metaprogram), using a typename in a parameter list isn't one of those cases in practice.

     

    Wrong again.  Consider the following, where Number is a class with a constructor taking an int:

    template <typename T>
    struct RECURSE
    {
    typedef typename RECURSE< RECURSE<T> >::BAD BAD;
    };

    typedef RECURSE<int> FOO;
    Number Bar (FOO::BAD);
    and
    struct FOO
    {
    const static int BAD = 5;
    };

    ...

    Number Bar (FOO::BAD);


    The first one will recurse forever on compilation. The second works just fine. Wicked, eh?
     

    And we see this sort of programming where....? 



  • @WeatherGod said:

    And we see this sort of programming where....?
     

    Who cares where we see it, or even if we see it?  The question is whether or not C++ has an undecidable grammar, and specifically, if the parameter list of a function definition can be undecidable.  Clearly, it can. 



  • @bstorer said:

    @Heron said:

    And to bstorer, you make several good points... But it's more of a theoretical problem than a practical problem, and it's just as much of a problem in C as it is in C++.  In practice, though, the compiler knows whether a given symbol is defined until "now" when it comes to a line of code (it keeps a lookup table), and it knows whether it's a typename or a variable.  So while technically it is true that you could create an example where a line of code would be undecidable (i.e. using a template metaprogram), using a typename in a parameter list isn't one of those cases in practice.

     

    Wrong again.  Consider the following, where Number is a class with a constructor taking an int:

    template <typename T>
    struct RECURSE
    {
    typedef typename RECURSE< RECURSE<T> >::BAD BAD;
    };

    typedef RECURSE<int> FOO;
    Number Bar (FOO::BAD);
    and
    struct FOO
    {
    const static int BAD = 5;
    };

    ...

    Number Bar (FOO::BAD);


    The first one will recurse forever on compilation. The second works just fine. Wicked, eh?
     

    I've refined this slightly to emphasize the significance:

    template<typename T>
    struct RECURSE {
    typedef typename RECURSE< RECURSE<T> >::X X;
    };

    template<>
    struct RECURSE<float> {
    const static int X = 5;
    };

    class Number { public: Number(int x){} };

    typedef RECURSE<int> BAD;
    typedef RECURSE<float> GOOD;

    //Line A: Compiles just fine, results in a Number object named Foo.
    Number Foo (GOOD::X);
    //Line B: Doesn't compile. Infinitely recurses in an attempt to resolve BAD::X.
    Number Foo (BAD::X);
    The trick here is that the compiler doesn't know whether lines A and B are global variables or function definitions until it resolves just what GOOD::X and BAD::X are.  And, of course, it can't resolve BAD::X.


  • If you'll notice, bstorer, I specifically said that in practice it's never a problem.  I doubt any of us have seen code like this outside of an academic setting (like this one).



  • @Heron said:

    If you'll notice, bstorer, I specifically said that in practice it's never a problem.  I doubt any of us have seen code like this outside of an academic setting (like this one).

     

    And if you'll notice, you specifically said:

    In practice, though, the compiler knows whether a given symbol is
    defined until "now" when it comes to a line of code (it keeps a lookup
    table), and it knows whether it's a typename or a variable.

    The second example gives a simple demonstration of how the compiler actually knows nothing of the sort when it comes to templates.  In fact, the compiler deliberately keeps its "knowledge" of a template data structure to a minimum until forced to do otherwise.  This is by design, and a result of the (in my opinion) kludgy way that templates are done in C++.

    Now, let's discuss that term "in practice."  Do you consider the STL to be used in practice?  What about Boost?  Both make frequent use of template metaprogramming.  Okay, maybe you don't use either one.  You hate generic programming, you don't believe in smart pointers, you roll your own container classes.  That's cool; I'm sure there are many developers out there who don't touch a whole lot of either library, save maybe string.  So now it's all okay, right?  I mean, sure, academically these things might be possible, but they don't matter.  We're not working in classrooms, after all.  A great theory, except for one key point: while you may not use those features of the language, the compiler has to be able to handle them because they're part of the language.  Check out The Design and Evolution of C++, there's all sorts of crap going on behind the scenes to resolve C++'s templates, complex scoping rules, ambiguous grammar, &c.

    I'm not trying to attack you, and though I'm being condescending, it's nothing personal and it's not (just) pedantry.  I'm trying to hammer home a very important point: this stuff is part of the language.  Dismissing criticism of it because you don't use it is not an acceptable strategy.



  • @Heron said:

    If you'll notice, bstorer, I specifically said that in practice it's never a problem.  I doubt any of us have seen code like this outside of an academic setting (like this one).

     

    You seem to miss the unfortunate fact that if such constructs is possible, it becomes fscking hard to write a compiler, debugger etc. that actually works. You can't make a compiler that only compiles "in practice" programs.



  • @ammoQ said:

    You seem to miss the unfortunate fact that if such constructs is possible, it becomes fscking hard to write a compiler, debugger etc. that actually works. You can't make a compiler that only compiles "in practice" programs.

    True, but you only have to write a working compiler once, whereas you use the language to create programs often. So while certain features might be a PITA to implement in your compiler, it might turn out to be worth it in the end. (E.g. templates in C++: it, IIRC, took some time before compilers implemented them correctly, but, at least, I use those features quite frequently.)

    And to get back to C++0x: it's been a while since i looked at the specs, but some features seemed nice (e.g. the recursive/variadic templates, the 'auto' type-thing, the lambda functions); lots of the stuff that was already available using boost::, but often with a less convenient syntax.



  • You're trying to use a malformed program to prove that writing a 'correct' compiler is impossible.

     

    That's just stupid. 

     

    Of course the compiler can't compile this. It'll generate an error, just like it's supposed to.



  • @Isuwen said:

    You're trying to use a malformed program to prove that writing a 'correct' compiler is impossible.

     

    That's just stupid. 

     

    Of course the compiler can't compile this. It'll generate an error, just like it's supposed to.

    That's not what bstorer has been doing. He showed an example of a grammatically correct C++ program which will not compile because C++'s grammar is undecidable. There is no one algorithm to determine whether a given string is valid C++ or not. This is true, as he showed. The fact that the compiler barfs an error supports his claim -- the reason it barfs is because it sets an artificial upper limit on the depth of template recursion, in spite of the specification that templates are [i]supposed[/i] to be Turing complete.



  • @poopdeville said:

    He showed an example of a grammatically correct C++ program which will not compile because C++'s grammar is undecidable.
     

    There is more to correctness than grammar. The program is logically incorrect. Infinite recursion is always a logical error. You should be praising the compiler for detecting it, rather than compiling through the heat death of the universe.

     

    And, for that matter, who gives a fuck? Whoever argued it is right : This example is stupid because it is ALWAYS an error. The compiler should not be expected to compile a program when you write shitty code like that. 


Log in to reply
 

Looks like your connection to What the Daily WTF? was lost, please wait while we try to reconnect.