C, C++, D Source Code Blocks in Org Mode

Table of Contents

Org Mode support for
C, C++
D

Introduction

Babel can evaluate C, C++, and D code.

As opposed to interpreted languages, which can be evaluated directly, C, C++, and D code is first compiled to an executable which is then run.

If a main method is not present in a code block then the entire block is wrapped in a trivial main function call.

Note: there used to be two separate library files, ob-C.el and ob-D.el. They have been merged in a single ob-C.el file which handle all three languages.

So, for example, the following simple code block can be evaluated and the results of evaluation inserted into the buffer.

#+begin_src C++ :includes <stdio.h>
  int a=1;
  int b=1;
  printf("%d\n", a+b);
#+end_src

#+results:
: 2

About C

C dates back in the 1970. It was devised by Kernighan & Ritchie. It was used to create the Unix kernel, and many of its utilities. Today it is still the base of the Linux & Unix kernel.

About C++

C++ was devised by Stroustrup in the 1980. The purpose was to enhance C with object programming. Among the features introduced by C++, there are:

  • templates and the Standard Template Library,
  • object programming, with class definition and inheritance,
  • functions and operators overloading,
  • exceptions.

About D

D is a C++-like language made by Digital Mars. It features:

  • C++ syntax
  • Built-in garbage collector
  • Strong type system
  • Meta-programming
  • Seamless assembler support
  • Usable as a scripting language
  • C binary compatibility

Requirements and Setup

1- You must have the compilers available on your computer. You may use only one of the three languages: there is no requirement to have all three installed.

  • C and C++ often come pre-installed. Popular compilers are the GNU ones, called gcc and g++. But others are usable as well.
  • For D, look at http://dlang.org/ for downloading and instructions. The compilers are called dmd and rdmd.

Eventually, the compilers must be in the PATH.

2- Make any or all languages available to Babel. Type:

M-x customize-variable org-babel-load-languages

and add the C language (capital "C", which gives access to C, C++, D)

Org Mode Features for C, C++, D Source Code Blocks

Header Arguments

:var VARIABLE=VALUE
A global C, C++, or D variable named VARIABLE will be declared and initialized with VALUE

Possible types for VARIABLE may be:

int,
double,
string or const char*,
type[]    // type = int, double, string, const char*
type[][]  // type = int, double, string, const char*

The later type, type[][], is used for variables storing Org tables

The type[] is used for lists or vectors declared in the header.

:cmdline
command line arguments to pass to the executable compiled from the code block
:flags
flags to pass to the compiler
:main
can be set to "no" to inhibit wrapping of the code block in a main function call
:includes
(C & CC+ only) accepts either a single string name, or a list of names of files to #include in the execution of the code block
(no term)
:import package:: (D only) An import statement will be declared in the D source before the source code
(no term)
:defines (C & C++ only):: just like :includes but for #defines lines at the top of the code

Sessions

There is no support for sessions

TODO Result Types

  • Which result types are supported?

TODO Other

  • Differences from other supported languages

Examples of Use

Hello World in C & C++

Here is Hello World!

This source code block:

#+begin_src C
  printf ("Hello World!");
#+end_src

yields this result (type C-c C-c in the source block):

Hello World!

Hello World in D

Here is Hello World!

This source code block:

#+begin_src D
  writefln ("Hello World!");
#+end_src

yields this result (type C-c C-c in the source block):

Hello World!

Note that:

  • if no main() is declared, a trivial one is automatically provided,
  • there is no directive like:
    • =#include "stdio.h"= (in C or C++)
    • import std.stdio; (in D)

    because those libraries are so common that they are always included.

Scalar variables

Variables may be declared outside the script. They are automatically inserted at the top of the script. Three types are supported, based on the look of the value:

  • string or const char*
  • int
  • double

Example in C or C++:

#+header: :var mystring="Sunday" :var myint=145 :var mydouble=3.14
#+BEGIN_SRC C
  printf ("mystring %s\n", mystring);
  printf ("myint    %d\n", myint);
  printf ("mydouble %g\n", mydouble);
#+END_SRC

yields this result (type C-c C-c):

mystring Sunday
myint 145
mydouble 3.14

Example in D:

#+header: :var mystring="Sunday" :var myint=145 :var mydouble=3.14
#+BEGIN_SRC D
  writefln ("mystring %s", mystring);
  writefln ("myint    %d", myint);
  writefln ("mydouble %g", mydouble);
#+END_SRC

yields this result (type C-c C-c):

mystring Sunday
myint 145
mydouble 3.14

If you want to see the expanded source code, without compiling a running it, just type C-c C-v v".

Process an Org Mode Table

How to handle a table

We take an Org mode table as input, process it, and output a new Org mode table.

This table will be input in the script, and iterated row by row:

nb sqr noise
zero 0 0.23
one 1 1.31
two 4 4.61
three 9 9.05
four 16 16.55

The table is converted to a variable in the script:

const char* somedata[5][3] = {...};  // in C & C++
string      somedata[5][3] = [...];  // in D

The header, if any, is available to the script as well:

const char* somedata_header[3] = { "nb", "sqr", "noise" };  // in C & C++
string      somedata_header[3] = [ "nb", "sqr", "noise" ];  // in D

The dimensions of the table are available:

int somedata_rows = 5;
int somedata_cols = 3;

Additionnally, an accessor function retrives a cell using the column name as found in the header:

const char* cell = somedata_h(3,"noise"); // "9.05" in C & C++
string      cell = somedata_h(3,"noise"); // "9.05" in D

Type C-c C-v v to look at the generate code without running it.

Note that table contents are (almost) always strings (as opposed to integers or floating point numbers). This allows to easily handle heterogeneous tables, and tables with missing values. To convert a string cell to a numeric value on the fly, use standard convertors:

int    cell = atoi(somedata_h(4,"sqr"));        // integer conversion in C & C++
double cell = atof(somedata_h(4,"noise"));      //  double conversion in C & C++
int    cell = to!int(somedata_h(4,"sqr"));      // integer conversion in D
double cell = to!double(somedata_h(4,"noise")); //  double conversion in D

Example in C & C++

This code:

#+header: :exports results
#+begin_src C++ :var somedata=somedata
  #include "stdlib.h"
  int main()
  {
    for (int i=0; i<somedata_rows; i++) {
      printf ("%2d ", i);
      for (int j=1; j<somedata_cols; j++) {
        const char* cell = somedata[i][j];
        printf ("%5s %5g ", cell, 1000*atof(cell));
      }
      printf("\n");
    }
    return 0;
  }
#+end_src

yields this result:

0 zero 0 0 0.23 230
1 one 1 1000 1.31 1310
2 two 4 4000 4.61 4610
3 three 9 9000 9.05 9050
4 four 16 16000 16.55 16550

Example in D

#+begin_src D :results output :var somedata=somedata :var TT="321" :var QQ=3.14
  void main()
  {
    foreach (i, row; somedata) {
      writef ("%2s %7s ", i, somedata_h(i,"nb"));
      foreach (j, cell; row)
        if (j) // skip 1st column
          writef ("%5s %5s ", cell, 1000*to!double(cell));
      writeln();
    }
  }
#+end_src

yields this result:

0 zero 0 0 0.23 230
1 one 1 1000 1.31 1310
2 two 4 4000 4.61 4610
3 three 9 9000 9.05 9050
4 four 16 16000 16.55 16550

Pure numeric table

This table is a pure numeric table.

3 3.3
4 4.1
5 5.9
6 6.5

In this special case, it is translated to a numeric table:

double MyTable[4][2] = { {3,3.3}, {4,4.1}, {5,5.9}, {6,6.5} };

If there is a blank cell among numeric cells, then the whole table falls back to the string case, where the blank cell is translated to the empty string "".

TODO Lists and vectors in the header

Shortcomings and known bugs

C++ vs. cpp

After the #+begin_src block header, both C++ and cpp are accepted to specify C++ language. However only C++ works for generated code visualization through C-c C-v v.

Pure numeric + header cast error

A type mismatch between strings and double cause an error when attempting to use the cell accessor with column name when the table is pure numeric.

Compilers customization

There is no customization of the compilers paths or names through the standard Emacs customization facility.

Documentation from the http://orgmode.org/worg/ website (either in its HTML format or in its Org format) is licensed under the GNU Free Documentation License version 1.3 or later. The code examples and css stylesheets are licensed under the GNU General Public License v3 or later.