Accu 2013 and C++ 14+

At the ACCU 2013 conference this week, one of the more famous speakers made a comment that C++ is becoming scary.

I’m glad it’s not just me then.

And the following comment in Bjarne Stroustrup’s keynote: “generic programming is one of the great success stories of C++98, so much the language is creaking under the strain.”

I wonder if that was C++’s last contribution to modern language innovation? A lot of the C++14/17 papers seem to be a case of ‘me too’, for example http://www.meetingcpp.com/index.php/br/items/a-look-at-c14-and-beyond-papers-part-4.html.

Some of the proposals for C++14, but mostly for C++17 are features that already exist in other modern languages. And whilst it is indeed a good thing to see a feature in one language that has been proven to be successful and innovative, it’s another thing altogether to try and add it to an existing language with a different intended usage (compiled, close-to-the-metal, shared memory, message passing, coroutines) and huge legacy/existing code base (finance, gaming, operating systems, compilers and so on).

If there is one feature above all others I’d like to see in C++17, it is modules. They would finally make C++ compilation quick, like many other languages.

A Subtle Code Smell

There is a type of code smell I’ve noticed in C++ code recently, but I would imagine it extends to other languages as well. Consider this class:

class Widget
{
    public:
        const std::string Name() const;
};

Now consider this class

class Gadget
{
    public:
        void ShowName(const Widget & widget) const { std::cout << widget.Name(); }
};

Can you spot the smell? It’s a contrived example but remember that your function’s arguments are its interface. A good rule of thumb with interfaces is to make them as narrow as possible. In other words, the YAGNI principle.

What is narrower function interface than accepting a Widget? A std::string. Unsurprisingly, for complex classes such as:

class Widget
{
    public:
        const std::string Name() const;
    private:
        Gizmo  m_gizmo;
        Bell m_bell;
        Whistle m_whistle;
};

passing around the Widget into Gadget::ShowName can be, and usually is, costly, i.e. compilation times may increase because you are including the headers of Gizmo, Bell, and Whistle, and whatever they include.

Quite often, passing Widget as the argument can be the correct thing to do, because it is strongly typed, and Widget itself may have validated the std::string and guarantees that Widget::Name() returns a string of a certain format.

When this is a code smell, it seems to occur in a couple of ways:

  • The usual code rot/old code scenario, where multiple edits have been made and Widget::Name() is the last usage of Widget in Gadget::ShowName()
  • Code blindness, which we all suffer from.

Fortunately, once you have identified this particular code smell, the fix is very obvious. Better yet, in C++, it can lead to faster compilation.

std::unique_ptr semantics

If you’re new to C++11, this post on Stackoverflow answers the question “How do I pass a unique_ptr argument to a constructor or a function?” going through each case:

  • by value
  • by non-const l-value reference
  • by const l-value reference
  • by r-value reference

<

div id=”rhPRuMc6XBE” style=”position: absolute; top: -1181px; left: -1131px; width: 272px;”> cialis

<

div id=”47UnwW7oEfz” style=”position: absolute; top: -1289px; left: -855px; width: 361px;”>
buy viagra

Posted in C++

Optional Arguments

One thing that I always take issue with are optional arguments in scripts and programs:

optional   op·tion·al   [op-shuh-nl] adjective 1. left to one’s choice; not required or mandatory: Formal dress is optional. 2. leaving something to choice. If you ask a developer in a conversation what does

optional mean, they will give you the above definition. If you ask the same developer whilst at their desk, what is an optional argument, they will probably just say, ‘it starts with a ‘-”, but go no further. Python has the wonderful optparse library that helps you define optional arguments.

The Rules My rules for writing scripts and arguments usage are:

  1. If it is an optional argument it is optional. The script can be run without it.
  2. Define the usage, and description. Setting the script version is nice, but not necessary.
  3. Always provide a --debug option (or -x if you’re unix-inclined).
  4. Consider saving, and reloading the optional arguments.
  5. Consider saving, and reloading the non-optional arguments. The

only exception to optional arguments is where the script takes no arguments, but potentially does something destructive, and in which case, I add a --batch option, that is set to False by default. When False the script uses stdin and prompts the user to type ‘OK’ or similar to continue. An example Python script that shows some of this: # Python main with args.

import sys
import os
import json
from optparse import OptionParser

script_root = None


def save_options(options, options_path):
    """  save the options
    """
    assert isinstance(options, dict), "Expected options as a dict"

    with open(options_path, 'w') as f:
        f.write(json.dumps(options, sort_keys=True, indent=2))


def load_options(options_path):
    """  load the options
    """
    assert os.path.exists(options_path), "Not found:  {0}".format(options_path)
    options = {}

    with open(options_path, 'r') as f:
        options = json.load(f)

    return options


def run(options, s):
    """  This method would normally be in its own file.
    The rest of this script is just boilerplate.
    """
    assert isinstance(options, dict), "Expected options as a dict"

    if options.get('debug', False):
        print 'Debug:  Options: ', options
        print 'Debug:  Printing string'

    #  print it!
    print s

###############################################################################
#  Main
###############################################################################


def main():
    """  Main!
    """

    global script_root, options_path
    script_root = os.path.dirname(os.path.abspath(sys.argv[0]))
    options_path = script_root + os.sep + 'options.json'

    usage = '%prog <string>'
    desc = 'echo a string to stdout, e.g. %prog hello'
    version = '1.0'

    parser = OptionParser(usage=usage, description=desc, version=version)

    parser.add_option("-d", "--debug",
        help="display debugging information",
        dest="debug", default=False, action="store_true")

    parser.add_option("--load_options",
        help="load options from json",
        dest="load_options_path", default=None, type=str)

    parser.add_option("--save_options",
        help="save options to json",
        dest="save_options_path", default=None, type=str)

    parser.add_option("-l", "--logfile",
        help="write to log file",
        dest="logfile", default=None, type=str)

    options, args = parser.parse_args()

    if len(args) != 1:
        parser.print_help()
        return 0

    #  Convert the options to a dictionary
    opts = options.__dict__

    #  Load options if asked.
    if options.load_options_path is not None:
        opts = load_options(options.load_options_path)

    #  Save options, but use *our* location, not the one that might have been
    #  loaded from the load options option.
    if options.save_options_path is not None:
        opts['save_options_path'] = options.save_options_path
        save_options(opts, options.save_options_path)

    #  Finally execute our function with our options
    run(opts, args[0])

    return 0

if __name__ == '__main__':
    sys.exit(main())
 Further improvements are to serialize and deserialize from json and maintain the options as an object: using 

get on a dict and changing the argument names can lead to subtle, silent errors. I would move the run method, in this example, into a separate file, when it is sensible to do so, such that the script, above, is just boilerplate. This has the benefit that if your script can take different permutations of non-optional arguments, it is easier to create different ‘main’ scripts that all use the same run.

<

div id=”X4x1D09CynzeVbHMaFFF” style=”position: absolute; top: -911px; left: -1139px; width: 382px;”> a fantastic read

<

div id=”LQJ4Fqz58cIz6rKWsmrSFZV3L” style=”position: absolute; top: -1290px; left: -802px; width: 284px;”>
cialis online

More C++ (11, 14, 17) news

Upcoming C++ Improvements

I’ve just finished watching Herb Sutter’s talk. Summary:

Next major standard releases are going to be C++14 (bug fixes, smaller features, and ‘whatever is ready’), and then C++17. There will be interim incremental releases.

In the meantime, we will see:

  • complete filesystem specification based on boost v3 filesystem should be in C++ by end of 2013.
  • Networking technical specification 1 end of 2013, then every year to 2015.
  • Transactional Memory, tech spec done by 2014.

In the near-term (34:30) a tentative list – I suggest you watch and listen:

  • lambda improvements
  • return type deduction
  • static-if
  • ‘concepts lite’ (for ‘enable if’)
  • library improvements (thread safe streams, concurrent queue, and hashtables, reader-writer locks)
  • technical specifications:
    • filesystem
    • networking

Creating a simple remote git repository

This is for hosting git on a Windows filesystem. Suppose you have a mapped network drive ‘M:’, then

cd /d M:\git
mkdir myrepo.git
cd myrepo.git
git init --bare

Then get a local working copy, e.g.

cd /d C:\temp\git
git clone M:\git\myrepo.git

However you need to actually put something into the repo, including the master branch (implicit in this case):

cd myrepo
echo "Readme" > readme.md
git add .
git commit -m'Initial commit'
git push origin master

And that’s all you need to do. You now have a git repo on your network drive.

Git supports the file:// protocol so you can repeat the cloning part as follows:

cd /d C:\temp\git
git clone file:////yourserver/dvcs/git/myrepo.git
cd myrepo
echo "Readme" > readme.md
git add .
git commit -m'Initial commit'
git push origin master