Wednesday, July 9, 2014

Simulate C++11 std::copy_n () function

Let's say you are using a compiler that doesn't have C++11 features on it. Here is a way to simulate std::copy_n (). I believe my implementation is correct.

Tested with Visual Studio 2008 and Visual Studio 2012 (Yes, I know VS2012 has std::copy_n)

    // Simulate C++11 std::copy_n
    template <class InputIterator, class Size, class OutputIterator>
    OutputIterator copy_n (InputIterator first, Size count, OutputIterator result)
    {
        if (count > 0) {
            for (Size n = 0; n < count - 1; ++n, ++first, ++result) {
                        *result = *first ;
            }
           
            *result = *first ; // We don't want to advance `first` again.
            ++result ; // `result` points to one past the last value.
        }

        return result ;
    }

Read one address and get two different values

This post is about fun with undefined behavior. There are a few different things going on:
  1. We are casting a struct to a int**.
  2. We are modifying the value of a constant private member.
  3. We are modifying the value of a constant variable on the stack.
When we read the address and value of size, the compiler is probably performing optimizations. Instead of reading the value of size, it's probably just replacing it with the literal 3.

Tested with Visual Studio 2012

#include <iostream>

struct PtrHolder
{
    PtrHolder (const int *p) : p (p)
    {
    }

private:
    const int *p ;
};

int main (void)
{
    const int size = 3 ;

    char buffer [size] = {} ;

    PtrHolder ph (&size) ;

    int **pp = reinterpret_cast <int **> (&ph) ;

    std::cout << "*pp: " << *pp << ", pp[0][0]: " << pp[0][0] << "\n" ;
    std::cout << "&size: " << &size << ", size: " << size << "\n" ;

    pp [0] [0] = 2 ;

    std::cout << "*pp: " << *pp << ", pp[0][0]: " << pp[0][0] << "\n" ;
    std::cout << "&size: " << &size << ", size: " << size << "\n" ;

    return 0 ;
}

Output
*pp: 0041FD28, pp[0][0]: 3
&size: 0041FD28, size: 3
*pp: 0041FD28, pp[0][0]: 2
&size: 0041FD28, size: 3

Print vector recursively

Someone asked a question on Stack Overflow about printing the contents of a vector recursively. The OP provided no code and the question was downvoted and eventually deleted. Here's a quick and dirty way to do it using iterators.

Tested with Visual Studio 2012.

#include <iostream>
#include <vector>

template <class Iterator>
void print (Iterator iter, Iterator end)
{
    if (iter == end) {
        return ;
    }

    std::cout << *iter << "\n" ;

    print (++iter, end) ;
}

int main (void)
{
    int vals [] = {5, 10, 15, 20} ;
    std::vector <int> v (vals, vals + 4) ;

    print (v.cbegin (), v.cend ()) ;

    return 0 ;
}