Friday, May 3, 2013

C++11 in gcc 4.7

/**
 * The last blog entry I made was all about lvalue vs. rvalue references.
 * I wanted to parlay that into a sweet beginners level entry example about
 * C++ rvalue references.
 *
 * After a quick googling I found a sweet article by Hinnant, Stroustrup
 * (yes, the Stroustrup), and Kozicki [1] about rvalue references entitled
 * "A Brief Introduction to Rvalue References". You're probably saying to
 * me, "JR, but I don't have a C++11 compiler!".
 *
 * If you are a newbie to C++11 and/or gcc, you may not know about the
 * g++ flag to enable C++11 features. Here's a simple script to compile
 * using C++11 extensions in gcc:
 *
 * g++ -std=c++11 main.cpp
 *
 * That's it. I tried this out on a simple "Hello C++11" program and everything
 * seemed to work. However, a simple hello world is insufficient to test
 * the C++11 features. So I want to try a simple rvalue reference example.
 */

#include <iostream>
#include <string>

#define PRINT_A_CREATION
//#define CPP_03

class A
{
    public:

    A()
    {
        #if defined PRINT_A_CREATION
        std::cout << "--> A Default Constructed" << std::endl;
        #endif
    }

    /**
     * We can output when we perform a copy.
     */
    A(A const& a)
    {
        #if defined PRINT_A_CREATION
        std::cout << "--> A Created via Copy Constructor!" << std::endl;
        #endif
        this->value = a.value;
        this->description = a.description;
    }

    A& operator=(A const& a)
    {
        #if defined PRINT_A_CREATION
        std::cout << "--> A uses Assignment Operator!" << std::endl;
        #endif
        this->value = a.value;
        this->description = a.description;
        return *this;   
    }

    int value;
    std::string description;

    /**
     * We are going to output the contents of this as a const sometimes,
     * so make sure we use the const qualifier!
     */
    void dump() const
    {
        std::cout << description << " - " << value << std::endl;
    }
};


/**
 * To illustrate rvalue references, I want a function that returns
 * a more complicated object than an int or string.
 * @return an object of A by value.
 */
A ReturnByValue()
{
    A a;
    a.value = 12234;
    a.description = "Hello C++11";
    return a;
}


int main(int argc, char** argv)
{
    // This is the first form where it is completely inefficient.
    // ReturnByValue
    A a1 = ReturnByValue();
    a1.dump();
   
    // The following is an error, because we can't take a reference
    // to a temporary.
    #if defined ERROR1
    A& a2 = ReturnByValue();
    a2.dump();
    #endif

    // This IS allowed by the standard [3]. I actually got served on
    // this in a meeting. :)
    A const& a3 = ReturnByValue();
    a3.dump();   

    // If you want to compile this with C++03 to insure results,
    // just enable the CPP_03 macro.
    #if !defined CPP_03
    // This is the new syntax of an rvalue reference in C++11. This
    // is kind of crazy because gcc will not work without enabling
    // C++11 (as documented above).
    A&& a4 = ReturnByValue();
    a4.dump();
    #endif

    // At this point I ran the example above with the macro
    // PRINT_A_CREATION enabled- what shocks me about this is
    // I don't see the copy constructor or assignment operator
    // being invoked.
}

/**
 * Sorry this was a little light on the C++ side and more elaborate about
 * how to enable C++11 extensions. I hope to explore rvalue references in a little
 * more detail tomorrow.
 *
 * In conclusion, g++ does allow us to compile C++11 code but it is still
 * experimental [4]. If g++ doesn't suit your fancy you should try clang. The only
 * downside to clang is its uncertain ease of availability in Windows.
 */

/**

REFERENCES

[1] - http://www.artima.com/cppsource/rvalue.html

[2] - http://linux.die.net/man/1/g++

[3] - http://herbsutter.com/2008/01/01/gotw-88-a-candidate-for-the-most-important-const

[4] - http://gcc.gnu.org/projects/cxx0x.html

[5] - http://clang.llvm.org

*/

No comments:

Post a Comment