Browsing some blogs recently I came across some interesting C++11 lambda code and thought it would be cool to try it out for myself. The idea of spinning up a project or even putting a new test in an existing project did not feel right. Wouldn’t a C++ REPL be useful for just these occasions?

A couple of web searches later turned up Cling which seemed to be just the thing. There was no distribution for OS X so my first thought was to build from source. This is a little more complex than I thought it should be. You need to set up a viable llvm development environment and run some patches to get cling to compile. I ran into a number of problems doing this both on my Mac and on an Ubuntu VM. (compilation, linking and version incompatibilities between the repositories). Really wished for some CI goodness at that point.

I ended up falling back on VMs and the Ubuntu binary distributions. If you are using Vagrant and VirtualBox I found that the 386 based Ubuntu 12.04 image would not run the binaries but the AMD one worked just fine.

Once I had the binaries working on the virtual machine I copied them over to more usual locations +/usr/local+ for more general use.

Cling uses clang under the hood and has the same command line arguments. I like to use C++11 at the moment and this can be specified in the usual way:

vagrant@vagrant-ubuntu-precise-64:~$ cling --std=c++11

****************** CLING ******************
* Type C++ code and press enter to run it *
*             Type .q to exit             *
*******************************************
[cling]$ 

Once you have the cling command shell running you have some additional commands available:

[cling]$ .help
Cling meta commands usage
Syntax: .Command [arg0 arg1 ... argN]

.q				           - Exit the program
.L <filename>	           - Load file or library
.(x|X) <filename>[args]	   - Same as .L and runs a function with signature
 	                             ret_type filename(args)
.I [path]			       - Shows the include path. If a path is given - 
	                         adds the path to the include paths
.@ 				           - Cancels and ignores the multiline input
.rawInput [0|1]			   - Toggle wrapping and printing the execution
			                 results of the input
.dynamicExtensions [0|1]   - Toggles the use of the dynamic scopes and the
                             late binding
.printAST [0|1]			   - Toggles the printing of input's corresponding
 	                             AST nodes
.help                      - Shows this information
[cling]$ 

At this point you can start writing code. Leaving the ‘;’ off the end allows cling to display information about the line that has been executed.

[cling]$ auto x = 10;
[cling]$ auto y = 11
(int) 11
[cling]$ x*y
(int) 110
[cling]$ auto foo = [](int x) { return x * 2; }
(class <lambda at input_line_8:2:13>) @0x7fb61fde7028
[cling]$ foo(100)
(int) 200
[cling]$