NOTE: Every post ends with "END OF POST". If you don't see it then open the full post in a separate page!

Controlling LEDs and switches with Raspberry Pi

Here is how you can control LEDs with switches with Raspberry Pi.

This is what you will get in the end:

RPi LEDs and switches

We will make a small game where we blink up the LEDs in a sequence and the player has to repeat it. Each switch controls a given LED.

If you are new to Raspberry Pi, then you may want to read this post first: https://feherenfekete.wordpress.com/2015/01/06/blinking-leds-on-raspberry-pi/

Ingredients

I used the pieces that came with the Raspberry Pi Model B+ Starter Pack (http://www.adafruit.com/product/2125):

  • Raspberry Pi Model B+
  • SD card with Raspbian Wheezy (Linux)
  • USB to TTL serial cable: for communication with the Pi
  • For the circuit
    • Breadboard
    • Adafruit Pi Cobbler Plus Kit- Breakout Cable
    • 3 pieces of 560 ohm resistors
    • 3 pieces of 10 Kohm resistors
    • 3 LEDs: red, green, blue
    • 3 switches
    • 4 + 2 + 6 pieces of male/male jumper wires

Wiring

Here is the schematic I used:

RPi_LEDs_switches_schematic

The connection of the switches uses pull-up resistors. For more information about this see the following links:

Here is some explanation for the schematic:

  • 5V+ : The 5V GPIO PIN of the Pi
  • GND PIN : We use two separate GND PINs of the Pi. One for the LEDs circuit and one for the switch circuit.
  • PIN 23, 24, 25, 16, 20, 21 : These are generic GPIO PINs of the Pi
  • R1, R2, R3 : 560 ohm resistors
  • R4, R5, R6 : 10K ohm resistors
  • S1, S2, S3 : switches
  • D1, D2, D3 : LEDs red, green and blue

Programming

We will use Python for this because it’s easy πŸ™‚

For simplicity, we hardcoded the LED sequences and we have only 3 of them.
First it shows a LED sequence. Then it waits for user input. The user has to repeat the sequence using the switches. Each switch controls one of the LEDs.
If the user presses the wrong swicth (i.e. wrong color) then we show an Error signal by blinking the red LED a few times. Then we repeat the sequence for the user to try again. She can try 3 times. After that, we move on to the next sequence.
If the user successfully repeated the sequence then we acknowlegde it by blinking all the LEDs a few times. Then we move on to the next sequence.
Each sequence is worth 3 points. Each failed attempt means a minus point.

pi@raspberrypi:~$ cat switches-and-leds.py
#!/usr/bin/env python

import time
import RPi.GPIO as gpio
import os

ledOff = 0
ledOn = 1

switchOff = 1
switchOn = 0

red = 0
green = 1
blue = 2
noColor = -1

redLed = 25
greenLed = 24
blueLed = 23

redSwitch = 21
greenSwitch = 20
blueSwitch = 16

colorToLedMap = { red : redLed, green : greenLed, blue : blueLed }
colorToSwitchMap = { red : redSwitch, green : greenSwitch, blue : blueSwitch }

switchStabilityTimeout = 0.025

def init():
        gpio.setmode(gpio.BCM)
        gpio.setup(redLed, gpio.OUT)
        gpio.setup(greenLed, gpio.OUT)
        gpio.setup(blueLed, gpio.OUT)
        gpio.setup(redSwitch, gpio.IN)
        gpio.setup(greenSwitch, gpio.IN)
        gpio.setup(blueSwitch, gpio.IN)

def cleanup():
        gpio.cleanup()

def setAllLeds(state):
        for color, led in colorToLedMap.iteritems():
                gpio.output(led, state)

def setLed(color, state):
        led = colorToLedMap[color]
        gpio.output(led, state)

class SwitchStateHandler:
        def __init__(self):
                self.wasOn = False
                self.count = 0
        def isStateStable(self, isOn):
                if isOn:
                        if self.wasOn:
                                self.count += 1
                        else:
                                self.wasOn = True
                else:
                        self.wasOn = False
                        self.count = 0
                if self.count == 3:
                        return True
                return False

def waitSwitchRelease():
        stateHandler = SwitchStateHandler()
        while True:
                redState = gpio.input(redSwitch)
                greenState = gpio.input(greenSwitch)
                blueState = gpio.input(blueSwitch)
                isOff = redState == switchOff and \
                        greenState == switchOff and \
                        blueState == switchOff
                if stateHandler.isStateStable(isOff):
                        return
                time.sleep(switchStabilityTimeout)

def readSwitch():
        waitSwitchRelease()
        setAllLeds(ledOff)
        redState = SwitchStateHandler()
        greenState = SwitchStateHandler()
        blueState = SwitchStateHandler()
        result = noColor
        while True:
                redIsOn = gpio.input(redSwitch) == switchOn
                greenIsOn = gpio.input(greenSwitch) == switchOn
                blueIsOn = gpio.input(blueSwitch) == switchOn
                if redState.isStateStable(redIsOn):
                        result = red
                        break
                if greenState.isStateStable(greenIsOn):
                        result = green
                        break
                if blueState.isStateStable(blueIsOn):
                        result = blue
                        break
                time.sleep(switchStabilityTimeout)
        if result != noColor:
                setLed(result, ledOn)
                waitSwitchRelease()
                setAllLeds(ledOff)
        return result

patterns = [[red, green, blue], [green, green, red, blue], [red, green, red, blue]]

def showPattern(pattern):
        for color in pattern:
                setAllLeds(ledOff)
                time.sleep(0.5)
                setLed(color, ledOn)
                time.sleep(0.5)
        setAllLeds(ledOff)

def showSuccessSignal():
        for i in xrange(0, 3):
                setAllLeds(ledOff)
                time.sleep(0.2)
                setAllLeds(ledOn)
                time.sleep(0.2)
        setAllLeds(ledOff)

def showFailedSignal():
        for i in xrange(0, 3):
                setAllLeds(ledOff)
                time.sleep(0.2)
                setLed(red, ledOn)
                time.sleep(0.2)
        setAllLeds(ledOff)

def guessPattern(pattern):
        for color in pattern:
                switch = readSwitch()
                if switch != color:
                        return False
        return True

def run():
        maxGuessCount = 3
        totalScore = 0
        for pattern in patterns:
                isGuessed = False
                guessCount = 0
                while not isGuessed and guessCount < maxGuessCount:
                        showPattern(pattern)
                        isGuessed = guessPattern(pattern)
                        if isGuessed:
                                print "Well done!"
                                showSuccessSignal()
                        else:
                                print "You missed it! Try again!"
                                guessCount += 1
                                showFailedSignal()
                score = (3 - guessCount)
                totalScore += score
                print "You earned %d points. Total score is %d." % (score, totalScore)

init()
try:
        run()
except KeyboardInterrupt:
        cleanup()

cleanup()

Now run it:

$ sudo ./switches-and-leds.sh

Enjoy! πŸ™‚

END OF POST


Blinking LEDs on Raspberry Pi

Here is how you can blink some LEDs with Raspberry Pi.

First of all, this is what you will end up with:

LEDs_Raspberry_Pi

You will have three LEDs being controlled programmatically from the Pi.
We will control the LEDs through the GPIO PINs by using Linux’s built-in GPIO sysfs.

Ingredients

I used the pieces that came with the Raspberry Pi Model B+ Starter Pack (http://www.adafruit.com/product/2125):

  • Raspberry Pi Model B+
  • SD card with Raspbian Wheezy (Linux)
  • USB to TTL serial cable: for communication with the Pi
  • For the circuit
    • Breadboard
    • Adafruit Pi Cobbler Plus Kit- Breakout Cable
    • 3 pieces of 560 ohm resistors
    • 3 LEDs: red, green, blue
    • 4 pieces of male/male jumper wires

Step 1: Boot up and establish serial connection

Connect the Pi to the breadboard with the breakout cable and the cobbler.
Connect the USB to TTL cable like this: https://learn.adafruit.com/adafruits-raspberry-pi-lesson-5-using-a-console-cable/connect-the-lead

  • Brown to RXD PIN (receive)
  • White to TXD PIN (transmit)
  • Black to GND PIN (ground)
  • Leave the Red cable unconnected. It is for power, but we will use the power adapter of the Pi for that.
  • Plug the USB plug to your computer.

Put your SD card with Raspbian into the Pi.
Plug the power cable to your Pi.
Plug the Pi’s power adapter to the wall socket.
Now the Pi is booting. You should see its red led lit up.

Run screen on your laptop:

sudo screen /dev/ttyUSB0 115200

Press ENTER and you should see something like this:

[    2.641363] usb 1-1: New USB device found, idVendor=0424, idProduct=9514
[    2.651493] usb 1-1: New USB device strings: Mfr=0, Product=0, SerialNumber=0
[    2.661640] hub 1-1:1.0: USB hub found
[    2.667076] hub 1-1:1.0: 5 ports detected
[    2.951168] usb 1-1.1: new high-speed USB device number 3 using dwc_otg
[    3.071404] usb 1-1.1: New USB device found, idVendor=0424, idProduct=ec00
[    3.079917] usb 1-1.1: New USB device strings: Mfr=0, Product=0, SerialNumber=0
[    3.108390] smsc95xx v1.0.4
[    3.177061] smsc95xx 1-1.1:1.0 eth0: register 'smsc95xx' at usb-bcm2708_usb-1.1, smsc95xx USB 2.0 Ethernet, b8:27:eb:9d:7e:2c
[    3.958510] udevd[156]: starting version 175
[    6.232318] bcm2708-i2s bcm2708-i2s.0: Failed to create debugfs directory
[    9.452151] EXT4-fs (mmcblk0p2): re-mounted. Opts: (null)
[    9.943347] EXT4-fs (mmcblk0p2): re-mounted. Opts: (null)
[   15.772181] FAT-fs (mmcblk0p1): Volume was not properly unmounted. Some data may be corrupt. Please run fsck.
οΏ½οΏ½
Raspbian GNU/Linux 7 raspberrypi ttyAMA0

raspberrypi login: 

OK. Now you can shutdown the Pi like this:

sudo shutdown -h now

Unplug the power adapter from the wall.
Unplug the USB cable from your computer.

Step 2: Wire up the circuit

Here is the schematic I used:

RPi LEDs schematic

  • GND PIN: One of the GPIO GND PIN of the Pi
  • R1, R2, R3: 560 ohm resistors
  • D1, D2, D3: Red, green and blue LEDs
  • PIN 23, 24, 25: These GPIO PINs will provide 3.3 Volts to each LED circuit

Step 3: Basic scripts for GPIO control

Script for initializing a LED PIN:

pi@raspberrypi:~$ cat gpio-init.sh 
#!/bin/sh

die() {
        echo "Error: $1"
        echo "Usage: gpio-init.sh pin-number in|out"
        exit 255
}

if [ $# -ne 2 ]; then
        die "Missing argument"
fi

PIN=$1
DIR=$2

echo -n "Exporting GPIO pin $PIN... "
echo $PIN > /sys/class/gpio/export || die "Cannot export"
echo "done"
sleep 1

echo -n "Setting direction to $DIR... "
echo $DIR > /sys/class/gpio/gpio$PIN/direction || die "Cannot set direction"
echo "done"
sleep 1

Script for putting PINs HIGH or LOW:

pi@raspberrypi:~$ cat gpio-write.sh 
#!/bin/sh

die() {
        echo "Error: $1"
        echo "Usage: gpio-write.sh pin-number value"
        exit 255
}

if [ $# -ne 2 ]; then
        die "Missing argument"
fi

PIN=$1
VAL=$2

echo -n "Writing $VAL to pin $PIN... "
echo $VAL > /sys/class/gpio/gpio$PIN/value || die "Cannot write"
echo "done"

Script for de-initializing LEDs:


pi@raspberrypi:~$ cat gpio-done.sh 
#!/bin/sh

die() {
        echo "Error: $1"
        echo "Usage: gpio-done.sh pin-number"
        exit 255
}

if [ $# -ne 1 ]; then
        die "Bad argument"
fi

PIN=$1

echo -n "Un-exporting GPIO pin $PIN... "
echo $PIN > /sys/class/gpio/unexport || die "Cannot un-export"
echo "done"
sleep 1

Step 4: Blink some LEDs

Script for defining common variables (e.g. PIN numbers) used by other scripts.

pi@raspberrypi:~$ cat blinker-def.sh 
# This is meant to be sourced from other scripts.

RED=23
GREEN=24
BLUE=25

Script for initializing the LEDs:

pi@raspberrypi:~$ cat blinker-init.sh 
#!/bin/sh

. ./blinker-def.sh

./gpio-init.sh $RED out
./gpio-init.sh $GREEN out
./gpio-init.sh $BLUE out

Script for blinking the LEDs:
We loop through some hardcoded LED patterns.

pi@raspberrypi:~$ cat blinker-blink.sh 
#!/bin/sh

. ./blinker-def.sh

while true; do
        for J in 100 010 001 101 011 100 110 001; do
                VAL_RED=`expr substr $J 1 1`
                VAL_GREEN=`expr substr $J 2 1`
                VAL_BLUE=`expr substr $J 3 1`
                ./gpio-write.sh $RED $VAL_RED
                ./gpio-write.sh $GREEN $VAL_GREEN
                ./gpio-write.sh $BLUE $VAL_BLUE
                sleep 1
        done
done

Script for de-initialization:

pi@raspberrypi:~$ cat blinker-cleanup.sh 
#!/bin/sh

. ./blinker-def.sh

./gpio-done.sh $RED
./gpio-done.sh $GREEN
./gpio-done.sh $BLUE

So, if you then run these in this sequence, you should get LEDs blinking in the predefined patterns:

$ sudo ./blinker-init.sh
$ sudo ./blinker-blink.sh # Press Ctrl-C when you got bored of it.
$ sudo ./blinker-cleanup.sh

END OF POST


Using auto for declaring variables of move-only types.


This post demonstrates how to use auto with move-only types.

In Declaration and initialization with auto, we showed that using auto for local declarations makes the code safer and more readable. It avoids writing declarations where we easily loose sight of the variable name. Like the first declaration in this example:

// Bad: The variable name is surrounded with "junk".
std::vector<std::string> myVariable { CreateStringVector(input1, input2) };

// Good: The variable name is always on the right side of "=".
auto myVariable = std::vector<std::string>{ CreateStringVector(input1, input2) };

Unfortunately, if you want to declare a variable of a move-only type with auto then you might try this:

#include <atomic>
#include <iostream>

int main()
{
    auto Counter = std::atomic<int>{22}; // Error: Won't compile.
    std::cout << Counter << std::endl;
    return 0;
}

But then you get this compilation error (clang 3.5.0):

prog.cc:6:10: error: call to implicitly-deleted copy constructor of 'std::__1::atomic<int>'
    auto Counter = std::atomic<int>{22};
         ^         ~~~~~~~~~~~~~~~~~~~~
/usr/local/libcxx-3.5/include/c++/v1/atomic:730:7: note: copy constructor of 'atomic<int>' is implicitly deleted because base class '__atomic_base<int>' has a deleted copy constructor
    : public __atomic_base<_Tp>
      ^
/usr/local/libcxx-3.5/include/c++/v1/atomic:649:7: note: copy constructor of '__atomic_base<int, true>' is implicitly deleted because base class '__atomic_base<int, false>' has a deleted copy constructor
    : public __atomic_base<_Tp, false>
      ^
/usr/local/libcxx-3.5/include/c++/v1/atomic:634:5: note: '__atomic_base' has been explicitly marked deleted here
    __atomic_base(const __atomic_base&) = delete;
    ^
1 error generated.

You get the error because the move-only type (std::atomic in this case) has a deleted copy constructor.
Luckily, all is not lost on our quest for Almost Always Auto. The solution is to use Universal References:

#include <atomic>
#include <iostream>

int main()
{
    auto && Counter = std::atomic<int>{22}; // OK
    std::cout << Counter << std::endl;
    return 0;
}

The above code compiles and runs.
To see what’s happening, let’s define our own move-only type:

#include <iostream>

class MoveOnly
{
public:
    MoveOnly() { std::cout << "MoveOnly::MoveOnly()" << std::endl; }
    MoveOnly(const MoveOnly &) = delete;
    MoveOnly(MoveOnly &&) { std::cout << "MoveOnly::MoveOnly(&&)" << std::endl; }
    MoveOnly & operator=(const MoveOnly &) = delete;
    MoveOnly & operator=(MoveOnly &&) = delete;
    ~MoveOnly() { std::cout << "MoveOnly::~MoveOnly()" << std::endl; }
    void Func() {}
};

int main()
{
    auto && moveOnlyRValue = MoveOnly{};
    moveOnlyRValue.Func();
    return 0;
}

Below is the output of the above code. No surprises or extra work, just as we’d want:

MoveOnly::MoveOnly()
MoveOnly::~MoveOnly()

To see the type that the compiler deduced for our variables, we can use the “Type Displayer” trick by Scott Meyers:

#include <iostream>

class MoveOnly
{
public:
    MoveOnly() { std::cout << "MoveOnly::MoveOnly()" << std::endl; }
    MoveOnly(const MoveOnly &) = delete;
    MoveOnly(MoveOnly &&) { std::cout << "MoveOnly::MoveOnly(&&)" << std::endl; }
    MoveOnly & operator=(const MoveOnly &) = delete;
    MoveOnly & operator=(MoveOnly &&) = delete;
    ~MoveOnly() { std::cout << "MoveOnly::~MoveOnly()" << std::endl; }
    void Func() {}
};

template <typename T>
class TypeDisplayer;

int main()
{
    auto && moveOnlyRValue = MoveOnly{};
    auto td1 = TypeDisplayer<decltype(moveOnlyRValue)>{};
    moveOnlyRValue.Func();
    
    auto moveOnly = std::move(moveOnlyRValue);
    auto td2 = TypeDisplayer<decltype(moveOnly)>{};
    moveOnly.Func();

    return 0;
}

This is what we get when we attempt to compile:

prog.cc:21:16: error: implicit instantiation of undefined template 'TypeDisplayer<MoveOnly &&>'
    auto td1 = TypeDisplayer<decltype(moveOnlyRValue)>{};
               ^
prog.cc:16:7: note: template is declared here
class TypeDisplayer;
      ^
prog.cc:25:16: error: implicit instantiation of undefined template 'TypeDisplayer<MoveOnly>'
    auto td2 = TypeDisplayer<decltype(moveOnly)>{};
               ^
prog.cc:16:7: note: template is declared here
class TypeDisplayer;
      ^
2 errors generated.

The compiler tells us that moveOnlyRValue is deduced as “MoveOnly &&” and moveOnly is deduced as “MoveOnly”.

Is it safe to do this? Is it safe to declare a move-only variable as “auto &&”? What happens?
Well, our variable will be an rvalue reference to a temporary object.

  • The question is the same as “Is it safe to declare our variable with “auto &””
  • Which is the same as “Is it safe to declare our variable with “Type &””
  • Which is similar to “Is it safe to declare our variable with “const Type &””

And we do this latter all the time to avoid unnecessary copies of temporaries:

const BigStuff & bigStuff = MakeBigStuff();

This causes trouble only if this reference outlives the object. For example, if we return it from a function, but luckily compilers already know about this pitfall and shout at us:

#include <iostream>

class MoveOnly
{
public:
    MoveOnly() { std::cout << "MoveOnly::MoveOnly()" << std::endl; }
    MoveOnly(const MoveOnly &) = delete;
    MoveOnly(MoveOnly &&) { std::cout << "MoveOnly::MoveOnly(&&)" << std::endl; }
    MoveOnly & operator=(const MoveOnly &) = delete;
    MoveOnly & operator=(MoveOnly &&) = delete;
    ~MoveOnly() { std::cout << "MoveOnly::~MoveOnly()" << std::endl; }
    void Func() const {}
};

MoveOnly & Shmunc()
{
    auto && moveOnlyRValue = MoveOnly{};
    return moveOnlyRValue; // Danger: Returning reference to temporary
}

int main()
{
    const auto & n = Shmunc();
    n.Func();
    return 0;
}

You get this warning if you enable warnings of your compiler, which you always should (e.g. -Wall for gcc and clang):

prog.cc:18:12: warning: returning reference to local temporary object [-Wreturn-stack-address]
    return moveOnlyRValue;
           ^~~~~~~~~~~~~~
prog.cc:17:13: note: binding reference variable 'moveOnlyRValue' here
    auto && moveOnlyRValue = MoveOnly{};
            ^                ~~~~~~~~~~
1 warning generated.

The solution is not to return references to local temporaries πŸ™‚ :

#include <iostream>

class MoveOnly
{
public:
    MoveOnly() { std::cout << "MoveOnly::MoveOnly()" << std::endl; }
    MoveOnly(const MoveOnly &) = delete;
    MoveOnly(MoveOnly &&) { std::cout << "MoveOnly::MoveOnly(&&)" << std::endl; }
    MoveOnly & operator=(const MoveOnly &) = delete;
    MoveOnly & operator=(MoveOnly &&) = delete;
    ~MoveOnly() { std::cout << "MoveOnly::~MoveOnly()" << std::endl; }
    void Func() const {}
};

MoveOnly Hunc()
{
    auto && moveOnlyRValue = MoveOnly{};
    return std::move(moveOnlyRValue);
}

int main()
{
    const auto & n = Hunc();
    n.Func();
    return 0;
}

We get this output:

MoveOnly::MoveOnly()
MoveOnly::MoveOnly(&&)
MoveOnly::~MoveOnly()
MoveOnly::~MoveOnly()

So, local variables with move-only types can be declared using “auto &&”.

References

END OF POST


Review: “Andrey Alexandrescu, Systematic Error Handling in C++” (Expected, ScopeGuard)

This is a review of a video lecture given by Andrey Alexandrescu on Systematic Error Handling in C++

Video:
* http://channel9.msdn.com/Shows/Going+Deep/C-and-Beyond-2012-Andrei-Alexandrescu-Systematic-Error-Handling-in-C
Slides:
* http://sdrv.ms/RXjNPR or
* https://onedrive.live.com/view.aspx?resid=F1B8FF18A2AEC5C5!1158&app=WordPdf&authkey=!APo6bfP5sJ8EmH4

Andrey Alexandrescu introduces two nice C++ classes to manage and handle errors in C++.
* Expected<T>
* ScopeGuard

Expected<T> is a template class. It is a bit similar to std::optional<T> (or boost::optional<T>) but it also carries the reason for an invalid value in the form of an exception object. Internally, it is a union that has either a T object or an exception.

It is easiest to understand it through a use-case, taken from Slide 28:

Expected<int> parseInt(const std::string& s)
{
    int result;
    ...
    if (nonDigit)
    {
        return Expected<int>::fromException(std::invalid_argument("not a number"));
    }
    ...
    if (tooManyDigits)
    {
        return Expected<int>::fromException(std::out_of_range("overflow"));
    }
    ...
    return result;
}

In the example above, we either return a valid result or an invalid result represented by an exception object. Note, that we do not throw the exception here. We just return it.

The caller then can decide whether to handle the exception immediately or (re)throw it. Example from Slide 29:

// Caller
string s = readline();
auto x = parseInt(s).get(); // Throw on error
auto y = parseInt(s); // Won’t throw
if (!y.valid()) {
    // Handle locally
    if (y.hasException<std::invalid_argument>()) {
        // Not an int
    }
    y.get(); // Just "re"throw
}

ScopeGuard is a class that executes the provided callable object at scope exit (i.e. at function exit and when exceptions occur).
Andrey provides some convenience macros fur using ScopeGuard but I think it is easier to see what it does without macros. Here is a usage example from slide 42:

// Assuming that action1() and action2() does not need neither cleanup nor rollback if they fail.

action1(); // Throws if fails
auto cleanup1 = ScopeGuard{[&] { doCleanup1(); }};
auto rollback1 = ScopeGuard{[&] { doRollback1(); }};

action2(); // Throws if fails
auto cleanup2 = ScopeGuard{[&] { doCleanup2(); }};
auto rollback2 = ScopeGuard{[&] { doRollback2(); }};

nextAction(); // Throws if fails

rollback1.dismiss();
rollback2.dismiss();

// cleanup1 and cleanup2 called at scope exit.

Although you can abuse e.g. std::unique_ptr to do RAII with a fake pointer (a pointer that does not point to a valid address) and a custom deleter, the resulting code may be misleading because it has nothing to do with pointers (the use of unique_ptr, the mysterious 0xfefefefe, the unused void* in doCleanup()).

// This code is a bit misleading. We just want to clean up but we mess with an API meant for pointers.

void doCleanup(void *)
{
    ...
}

void Action()
{
    ...
    auto cleanup = std::unique_ptr<void, decltype(doCleanup)*>{
                       reinterpret_cast<void *>(0xfefefefe), doCleanup };
    ...
    // doCleanup() called at scope exit or upon exception.
}

ScopeGuard provides a clear API for using RAII with unsafe/legacy code.

END OF POST


Using std::unique_ptr (RAII) with malloc() and free()


This is a short post about using std::unique_ptr with malloc() and free(). Although, it can be used with other resource management functions too (files, sockets, etc.).

Often, when working with legacy C and C++ code, we see usages of malloc() and free(). Just like new and delete, explicit memory management should be hidden in the guts of libraries whenever possible and never be exposed to the casual programmer.

It would be great if the legacy code could be easily changed to use std::make_unique() to make it nice clean and safe at the same time. Unfortunately, std::make_unique() uses new and delete operators internally. So, if our legacy code uses some custom functions to allocate and deallocate memory then we may be forced to do more refactoring than we might have time for (e.g. to use new expressions instead of custom or malloc based allocators).

Luckily, we can still get the benefit of RAII by using std::unique_ptr by trading off some cleanliness.
But std::unique_ptr takes a deleter type. No problem, we have decltype() to the rescue!

#include <memory>

int main()
{
    auto Data =
        std::unique_ptr<double, decltype(free)*>{
            reinterpret_cast<double*>(malloc(sizeof(double)*50)),
            free };
    return 0;
}

The decltype(free) gives back a function type of “void (void*)” but we need a pointer to a function. So, we say “decltype(free)*” which gives us “void (*)(void*)”. Excellent!

A bit awkward, but it is still nice, since it does RAII (automatic free) and both the allocator (malloc()) and the deallocator (free()) is clearly visible to the reader.

With decltype() we don’t have to write our own deleter functor like in this example:

#include <memory>

struct MyDeleter
{
    void operator()(double *p) { free(p); }
};

int main()
{
    auto Data =
        std::unique_ptr<double, MyDeleter>{
            reinterpret_cast<double*>(malloc(sizeof(double) * 50)) };
    return 0;
}

Also, with decltype() we don’t have to spell out the type of the deleter like in this example:

#include <memory>

int main()
{
    auto Data =
        std::unique_ptr<double, void(*)(void*)>{
            reinterpret_cast<double*>(malloc(sizeof(double) * 50)),
            free };
    return 0;
}

So, with std::unique_ptr you can quickly hack RAII into legacy code. However, as a general guideline, prefer refactoring legacy code using modern C++.

END OF POST


shared_ptr polymorphic magic pitfall


Pitfall in the polymorphic “magic” of std::shared_ptr

In [Sutter] we read:
“If A is intended to be used as a base class, and if callers should be able to destroy polymorphically, then make A::~A public and virtual. Otherwise make it protected (and not-virtual).”

Then in [ACCU], the author writes that if you use shared_ptr for polymorphic destruction then you may omit the virtual destructor. The reason for this can be read from [Arena].

In short, through it’s template code, the shared_ptr remembers the pointer type used during construction. For example, if you say “shared_ptr<Base>{new Derived{}}” then shared_ptr will internally store a Derived*. If you say “shared_ptr<Base>{new Base{}}” then it stores a Base*. Then when the shared_ptr is destructed, it calls delete on the stored pointer. Naturally, with non-virtual destructors, for Base* it will call Base::~Base and for Derived* it will call Derived::~Derived.

If you are not careful and blindly follow the example in [ACCU], there is a nasty surprise waiting for you!
Let’s take the following example:

#include <iostream>
#include <memory>

struct A
{
    ~A() { std::cout << __FUNCTION__ << std::endl; }
};

struct Base
{
    // No virtual dtor!
};

struct Derived : public Base
{
    Derived() : m_pA{new A{}} {}
    A m_A;
    std::unique_ptr<A> m_pA;
};

int main()
{
    {
        std::cout << "\nDelete Derived via Base* : A::~A() NOT CALLED" << std::endl;
        Base *p = new Derived{};
        delete p;
    }
    {
        std::cout << "\nDelete Derived via shared_ptr<Base> with Derived* : A::~A() called" << std::endl;
        std::shared_ptr<Base> sp{new Derived{}};
    }
    {
        std::cout << "\nDelete Derived via make_shared<Derived> : A::~A() called" << std::endl;
        std::shared_ptr<Base> sp{std::make_shared<Derived>()};
    }
    {
        std::cout << "\nDelete Derived via shared_ptr<Base> with Base* : A::~A() NOT CALLED" << std::endl;
        Base *p = new Derived{};
        std::shared_ptr<Base> sp{p};
    }
    return 0;
}

Base does not have a virtual destructor, so if we delete a Derived pointer via Base then A::~A will not be called. Classic memory leak candidate.
The above code gives the following output:

Delete Derived via Base* : A::~A() NOT CALLED

Delete Derived via shared_ptr<Base> with Derived* : A::~A() called
~A
~A

Delete Derived via make_shared<Derived> : A::~A() called
~A
~A

Delete Derived via shared_ptr<Base> with Base* : A::~A() NOT CALLED

The first call is as expected, since Base has non-virtual destructor, A is not destructed. On the other hand, via the “magic” of shared_ptr, in the 2nd and 3rd cases, Derived::~Derived (and thus A::~A) gets called even thou we have a shared_ptr<Base>. The 4th example has a surprise: although we use again a shared_ptr with a pointer to a Derived object, shared_ptr calls Base::~Base because it was initialized with a Base*. In this case shared_ptr cannot see that the provided Base* pointer actually points to a Derived object.

shared_ptr<Base> calls Derived::~Derived only if it is constructed directly with a pointer of type Derived*. If you construct shared_ptr<Base> with a Base* then it will not call Derived::~Derived, it will call ~Base::Base. The magic does not happen!

Also, in [Flaming] we read this:

“Classes that have custom destructors, copy/move constructors or copy/move assignment operators should deal exclusively with ownership. Other classes should not have custom destructors, copy/move constructors or copy/move assignment operators.”

But notice in our example above that neither Base nor Derived manage resources. Derived uses only self-destructing objects internally. So one might think that there is no ownership issue here, so we erroneously decide not to provide a “custom (virtual) destructor”. So the above should read like this:

“Classes that have custom destructors, copy/move constructors or copy/move assignment operators should deal exclusively with ownership. Other classes should not have custom destructors, copy/move constructors or copy/move assignment operators except for [Sutter].” πŸ™‚

Conclusion
No matter how “smart” your pointer to Derived is and no matter if you use everywhere only self-destructing objects (e.g. RAII), use a virtual desctructor for polymorphic deletion!

Again, as stated in [Sutter]:
“If A is intended to be used as a base class, and if callers should be able to destroy polymorphically, then make A::~A public and virtual. Otherwise make it protected (and not-virtual).”

References

END OF POST


Emulating in, out and inout function parameters – Part 2


Emulating in, out and inout function parameters in C++.

This is the continuation of Part 1 of this post.

In Part 1, we created classes to represent Input, Output and Input-Output parameters and arguments.
Here is an example how those classes can be used:

#include "param_inout.hpp"
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
using namespace param_inout;
using namespace std;
#define PRINT(arg) cout << __FUNCTION__ << ":" << __LINE__ << ": "<< arg << " " << endl

double func1(inp<int> p) {
    // p = 1; // Error: p is read-only.
    return p * 2.2;
}

void func2(outp<int> p) {
    // int a = p; // Error: p is write-only.
    p = 88;
}

void func3(inoutp<string> p) {
    auto t = string(p); // p is readable.
    p = "Hello ";       // p is writable.
    p = string(p) + t;  // p is readable and writable.
}

void func4(inp<string> pattern,
           inp<vector<string>> items,
           inoutp<string> message,
           outp<int> matchCount) {
    PRINT(message.arg());
    auto& ritems = items.arg();
    matchCount = count_if(begin(ritems), end(ritems),
        [&](const string& a) { return a.find(pattern) != string::npos; });
    message = "Done";
}

void func5(inp<int> p1, outp<int> p2, inoutp<string> p3) {
    // func1(p1); // Error! Good! inp::inp(const inp&) is private.
    func1(ina(p1));
    func2(outa(p2));
    func3(inouta(p3));
}

int main() {
    // auto a = func1(ina(2.2)); // Error: Cannot convert ina<double> to ina<int>
    // auto a = func1(2); // Error: inp::inp(const int&) is private.
    auto a0 = func1(ina(static_cast<int>(2.2)));   PRINT(a0);
    auto a1 = func1(ina(2));                       PRINT(a1);
    auto a2 = 0;                func2(outa(a2));   PRINT(a2);
    auto a3 = string{"world!"}; func3(inouta(a3)); PRINT(a3);

    auto a4 = vector<string>{"avocado", "apple", "plum", "apricot", "orange"};
    auto a5 = string{"Searching..."};
    auto a6 = 0;
    func4(ina(string{ "ap" }), ina(a4), inouta(a5), outa(a6));
    PRINT(a5);  PRINT(a6);

    func5(ina(5), outa(a6), inouta(a5));  PRINT(a5); PRINT(a6);

    return 0;
}

This example code produces the following output:

main:47: 4.4
main:48: 4.4
main:49: 88
main:50: Hello world!
func4:30: Searching...
main:56: Done
main:56: 2
main:58: Hello Done
main:58: 88

In the code example above, it is clear at the parameter declaration how each parameter is used by the function. Also, for declaration, we chose the convention to include a trailing “p” after the category. For example, outp signifies an Output Function Parameter. It says that it’s for output and it also says that it’s a parameter (i.e. not an argument).

At the call sites, we pass function arguments using ina (input), outa (output) and inouta (input and output). This way, we can clearly see that they are Function Arguments (not parameters); and how the function is going to use those arguments. No surprises.

It is also obvious how to construct function declarations ourselves. For example, the simple functions at the beginning of this post may be declared like this, regardless who does it:

void f(inoutp<string> s);
void g(inp<string> s);

void caller() {
  auto a1 = string{"hello"};
  f(inouta(a1));
  g(ina(a1));
}

And our std::vector example will become this:

void f(inp<vector<string>> v);

It is clear what is happening both at the declaration and at the call site. Also, this convention is much easier and obvious to follow.

References

References about the complexity of function parameter declaration guidelines

END OF POST