Anti-tutorial



  • I appreciate the efforts of people who write various language tutorials in an effort to teach others. Occasionally however, I come across attempts that while most likely well intentioned, should have the guy who wrote it castrated, his hands cut off and tongue ripped out to ensure there's no way he can ever reproduce and create another such site:

     



  • Could you educate us, the less aggressive members of the society, about the wrongnesses and evil deeds the author of that site commited? I mean, other than the output examples snapping to the right edge of the screen, rather than to the left.



  • @goose said:

    Could you educate us, the less aggressive members of the society, about the wrongnesses and evil deeds the author of that site commited? I mean, other than the output examples snapping to the right edge of the screen, rather than to the left.
    I don't get it, either.  I just flipped through it quickly, but it doesn't look like that bad of a first introduction to C++ for C programmers.  It glosses over a lot of details, but I didn't see anything jump out at me that would necessitate this kind of violence.



  • Dunno if I'd say it's so bad as to be worthy of opening up a whole can of woop-ass on the author, but: 

    <font color="#0f0000" size="+4">5. </font>

    A variable can be initialised by a calculation involving other variables:

    That's bogus; you can do that ever since K'n'R.

    <font color="#0f0000" size="+4">8. </font>

    It is possible to make one variable be another:
    That is a fairly badly misleading oversimplification of the concept of a reference.

    <font color="#0f0000" size="+4">10. </font>

    If a function contains just simple lines of code, doesn't use for loops or the like, it can be declared inline. This means its code will be inserted everywhere the function is used.
    Not true.  You can mark anything you like inline; the compiler will decide for itself whether it's too complex or not.  Also, omits the crucial significance of function bodies defined inside the class declaration being automatically inlined.

    That's somewhat like a macro
    It's misleading to describe macros and inline functions as "somewhat [a]like" without mentioning the far more significant ways in which they are not at all alike.

    You know the classical control structures of C: for, if, do, while, switch... C++ adds one more control structure named EXCEPTION:

    That's a pretty bad category error, confusing between syntactical language structures and the concept of a data structure / class which is a semantic concept in the language.  Should say "adds one more control structure called try...catch".

    <font color="#0f0000" size="+4">12. </font>

    It is possible to define default parameters for functions:


    using namespace std;
    #include <iostream>

    double test (double a, double b = 7)
    {
    return a - b;
    }
    Very bad style placing the default in the definition; it should be in the declaration only, or you can get very hard to track bugs if you write one default in the function body and another in the prototype - calls to the function from within the same source file get one default argument value, calls from external source files another.

    <font color="#0f0000" size="+4">13. </font>

    One important advantage of C++ is the OPERATOR OVERLOAD. Different functions can have the same name provided something allows the compiler to distinguish between them: number of parameters, type of parameters...

    Really should have mentioned return type there, and CV qualifiers, and reference-ness.

    <font color="#0f0000" size="+4">19. </font>

    If you cast an object like a vector, everything will happen correctly. For example, if vector k contains (4, 7), after the cast m = k the vector m will contain (4, 7) too. The values of k.x and k.y have simply been copied to m.x and m.y. Now suppose you're playing with objects like the person class above. Those objects contain a pointer to a character string. If you cast the person object by writing p = r it is necesary that some function does the work to make p be a correct copy of r.
    "Cast"?  WTF is he writing cast for when he means "assign"?  Poor, confusing and incorrect use of basic terminology throughout.

    I got bored around here.  It's a pretty low-quality tutorial and exactly the sort of thing that people who have taken to heart will waste time having to unlearn and relearn stuff properly.  Still not sure about the castration though.  Maybe his kids, or his kid's kids, or his kid's kid's kids can evolve some brains.



  • @bstorer said:

    @goose said:

    Could you educate us, the less aggressive members of the society, about the wrongnesses and evil deeds the author of that site commited? I mean, other than the output examples snapping to the right edge of the screen, rather than to the left.
    I don't get it, either.  I just flipped through it quickly, but it doesn't look like that bad of a first introduction to C++ for C programmers.  It glosses over a lot of details, but I didn't see anything jump out at me that would necessitate this kind of violence.

    The only really terrible thing I could find was:

     

    @tutorial said:

    <font color="#0f0000" size="+4">11. </font>

    You know the classical control structures of C: for, if, do, while, switch... C++ adds one more control structure named EXCEPTION:


    using namespace std;
    #include <iostream>
    #include <cmath>

    int main ()
    {
    int a, b;

    cout << "Type a number: ";
    cin >> a;
    cout << endl;

    try
    {
    if (a > 100) throw 100;
    if (a < 10) throw 10;
    throw a / 3;
    }
    catch (int result)
    {
    cout << "Result is: " << result << endl;
    b = result + 1;
    }

    cout << "b contains: " << b << endl;

    cout << endl;

    // another example of exception use:

    char zero [] = "zero";
    char pair [] = "pair";
    char notprime [] = "not prime";
    char prime [] = "prime";

    try
    {
    if (a == 0) throw zero;
    if ((a / 2) * 2 == a) throw pair;
    for (int i = 3; i <= sqrt (a); i++)
    {
    if ((a / i) * i == a) throw notprime;
    }
    throw prime;
    }
    catch (char *conclusion)
    {
    cout << "The number you typed is "<< conclusion << endl;
    }

    cout << endl;

    return 0;
    }


    Output
    Type a number: 5

    Result is: 10
    b contains: 11

    The number you typed is prime





     



  • Just the first example is good enough for me to hack his head with a hammer:

    "There is a new way to #include libraries (the old method still works yet the compiler complains). The .h extension is not used any more, and the names of standard C libraries are written beginning with a c. In order for the program to use these libraries correctly using namespace std; has to be added:"

    The compiler doesn't complain about including <stdio.h> and not <cstdio>.

    The true correct way to use the C++ standard library is to never ever EVER even THINK about adding that "using namespace std;" line. You are free to do "using std::cout;" or similar, but NEVER import the whole std namespace in the global namespace AND call it the correct way.



  • @rizzuh said:

    Just the first example is good enough for me to hack his head with a hammer:

    "There is a new way to #include libraries (the old method still works yet the compiler complains). The .h extension is not used any more, and the names of standard C libraries are written beginning with a c. In order for the program to use these libraries correctly using namespace std; has to be added:"

    The compiler doesn't complain about including and not .

    The true correct way to use the C++ standard library is to never ever EVER even THINK about adding that "using namespace std;" line. You are free to do "using std::cout;" or similar, but NEVER import the whole std namespace in the global namespace AND call it the correct way.

    Are you smoking the marijuana grass?  What's wrong with importing std?  I've rarely seen code that doesn't do it and it's a sight better than having "std::" all over your code or having dozens of using statements.



  • @rizzuh said:

    Just the first example is good enough for me to hack his head with a hammer:

    "There is a new way to #include libraries (the old method still works yet the compiler complains). The .h extension is not used any more, and the names of standard C libraries are written beginning with a c. In order for the program to use these libraries correctly using namespace std; has to be added:"

    The compiler doesn't complain about including and not .

    The true correct way to use the C++ standard library is to never ever EVER even THINK about adding that "using namespace std;" line. You are free to do "using std::cout;" or similar, but NEVER import the whole std namespace in the global namespace AND call it the correct way.

    I could very well be a tard but, uh... why not?


  • Discourse touched me in a no-no place

    @blakeyrat said:

    @rizzuh said:

    [...]You are free to do "using std::cout;" or similar, but NEVER import the whole std namespace in the global namespace AND call it the correct way.

    I could very well be a tard but, uh... why not?

    Ostensibly namespace pollution/clashes.

    As long as it doesn't appear in header files that (might) get re-used, it's not usually a problem.

    However http://osdir.com/ml/gcc.libstdc++.devel/2002-11/msg00260.html has an example where it bit someone



  • Buffer overflow in 3! IIRC std::cin does odd things if it gets invalid input.



  • @DaveK said:

    13.

    One important advantage of C++ is the OPERATOR OVERLOAD. Different functions can have the same name provided something allows the compiler to distinguish between them: number of parameters, type of parameters...

    Really should have mentioned return type there, and CV qualifiers, and reference-ness.

    It also seems the author is confusing operator overloading with function overloading.



  • @DaveK said:

    Really should have mentioned return type there
    I don't think you can use the return type of an operator or function to do operator or function overloading.  If C++ allows this then C++ is the most fucked language of all time.



  • @tster said:

    I don't think you can use the return type of an operator or function to do operator or function overloading.

     

    Sure one can do that. Look at Haskell's fromInteger, toEnum etc.

    Of course you need really strong typing for that.



  • @Ilya Ehrenburg said:

    @tster said:

    I don't think you can use the return type of an operator or function to do operator or function overloading.

     

    Sure one can do that. Look at Haskell's fromInteger, toEnum etc.

    Of course you need really strong typing for that.

     

    This thread is about C++...


  • Discourse touched me in a no-no place

    @tster said:

    If C++ allows this then C++ is the most fucked language of all time.
    It doesn't. That doesn't stop people idiots trying to work around it though: http://www.codeproject.com/KB/cpp/returnoverload.aspx



  • @PJH said:

    @tster said:
    If C++ allows this then C++ is the most fucked language of all time.
    It doesn't. That doesn't stop people idiots trying to work around it though: http://www.codeproject.com/KB/cpp/returnoverload.aspx
     

    Oh excellent, you see the version of my post the CS shit out with an SQL exception.



  • @tster said:

    I don't think you can use the return type of an operator or function to do operator or function overloading.  If C++ allows this then C++ is the most fucked language of all time.

    FTFY.



  • @tster said:

    @PJH said:

    @tster said:
    If C++ allows this then C++ is the most fucked language of all time.
    It doesn't. That doesn't stop people idiots trying to work around it though: http://www.codeproject.com/KB/cpp/returnoverload.aspx
     

    Oh excellent, you see the version of my post the CS shit out with an SQL exception.

    If only Community Server had stuck with the classical for, if, do, while and switch control structures and not tempted fate by using fancy exceptions!

     

    According to this tutorial, the proper way to do this would have been:

     

    try {

        if (save_post) {

            throw "INSERT INTO posts (user_id, thread_id, post_text) VALUES (?, ?, ?)";

        } else if (view_posts) {

            throw Db.query("SELECT * FROM posts WHERE (thread_id = ?)", thread_id);

        } else {

            throw -1; // error!

        }

    } catch....



  • @tster said:

    @DaveK said:

    Really should have mentioned return type there
    I don't think you can use the return type of an operator or function to do operator or function overloading.  If C++ allows this then C++ is the most fucked language of all time.

    Yeh, complete thinko there, ploughing through that tedious drivel caused major parts of my frontal lobes to get really bored and fall asleep while I was still typing.  Next time I'll just take OP's word for it that the guy deserves to die and not go and give myself brain damage trying to actually read the damn thing...

     


  • Discourse touched me in a no-no place

    @tster said:

    Oh excellent, you see the version of my post the CS shit out with an SQL exception.
    That one passed me by - explain please?



  • @PJH said:

    @tster said:
    Oh excellent, you see the version of my post the CS shit out with an SQL exception.
    That one passed me by - explain please?
     

    Some people see this:

    @tster said:

    I don't think you can use the return type of an operator or function to do operator or function overloading.  If C++ allows this then C++ is the most fucked language of all time.

    I see this

    @tster said:

    This thread is about C++...

    I posted the first and the forum gave me an error screen with some SQL exception.  I went back to the page and didn't see my post.  I was to lazy to retype the whole thing, so instead I posted the second shorter version.  I still see the second version, but I think some people are seeing the first version.

    I'm a fucking moron.



  • @PJH said:

    @tster said:
    If C++ allows this then C++ is the most fucked language of all time.
    It doesn't. That doesn't stop people idiots trying to work around it though: http://www.codeproject.com/KB/cpp/returnoverload.aspx
     

     

    Why is it so bad? I'd consider the following to wrap things like boost::lexical_cast (even though it is rather limited in what it can do) :)

    #include <iostream>
    #include <boost/lexical_cast.hpp>

    class from_string
    {
        const std::string& s;
    public:
        from_string(const std::string& s): s(s) {}
        template <class T>
        operator T () const
        {
            return boost::lexical_cast<T>(s);
        }
    };

    int main()
    {
        int i = from_string("21");
        std::cout << i * 2 << '\n';
        //std::cout << from_string("21") * 2 << '\n'; //may-be overload from_string for all operators as well???
    }

    To make the commented-out line compile, may-be add all (binary) operator overloads, a la

    template <class T>
    T operator* (const from_string& fs, const T& t)
    {
        return static_cast<T>(fs) * t;
    }



  •  Wait, you can throw ints and strings in C++?!



  • @AngelSL said:

     Wait, you can throw ints and strings in C++?!

    Let's start throwing handles to enterprisey in-house stack trace objects! Yay!



  • @AngelSL said:

     Wait, you can throw ints and strings in C++?!

    You can throw any data-type, which includes custom data types (classes, unions, structs, typedefs) built-in types, and pointers.


Log in to reply