C, C++ and C++/CLI cheat sheet

No explanation of the basic concepts, just a memory help when you don’t use C/C++ frequently, or if you’re a beginner with some bases.

First question: why pointers? Answers: because functions arguments are passed by value in C and C++. Because arrays and strings are crazy in C.

How to read pointers

Here is a handy way of remembering how pointers syntax works.

In variable declaration

Go from the right to the left of the declaration, from the innermost parenthesis, going back to the right when hitting “)”

  • Read the name of the declaration
  • *  is “a pointer to”
  • []  is “an array of”
  • ()  is “a function returning”
  • Finally, read the type

int *p[]; reads “p is an array of pointers to int”.
int *(*foo())();  reads “foo is a function returning a pointer to a function returning a pointer to int”.

In variable usage

Variable usage reads from left to right.

  • Determine “get” (read variable) or “set” (write variable)
  • *  is “the value pointed to by”
  • &  is “the address of”
  • [i]  is “the element at position i”
  • Read the variable name

*p = 5;  reads “set the value pointed to by p”.
x = &i;  reads “get the address of i”.
printf("%i", *foo[0]);  reads “get the value pointed to by the element at position 0 of foo”.

C pointers

Manipulating a variable through a pointer is called dereferencing. It is used through an indirection expression.
Manipulating pointers through variables is called decaying.

Given an integer:

  • Create an pointer:
  • Get the memory location of the variable:
  • Get the value of the variable:
  • Set the value of the variable:
  • Setting a pointer to null allows to assign it to a variable later:

C arrays

Arrays mostly can’t be manipulated directly, but rather through pointers.
The variable array  is, for most intents and purposes, a pointer to the first element of the array (until it’s incremented).

Given an array of integers:

  • This doesn’t really creates an array. It creates 3 integers side-by-side, and stores the memory location of the first one.
  • array == &array == &array[0]
  • When you pass an array as an argument to a function, you really pass a pointer to the array’s first element, because the array decays to a pointer.
  • Incrementing a pointer to an array really moves the pointer to the next element of the array (the pointer is incremented by the size of the type of the pointer).
  • The subscript operator (the [] in array[0]) has nothing to do with arrays themselves, you can also use it on a pointer:

C structures

Given a structure:

  • Accessing members of the structure through the variable:
  • Accessing the members through a pointer:

C++ references

C++ is much less in love with pointers than C, and prefers using reference variables. They are mostly used in the same way as pointers, but their address can’t change (they always points to the same variable).
The main usage of a reference variable is for function parameters, to pass the variables by reference (by default it’s by value), which allows to not use pointers.

Given an integer:

  • Create a reference to a variable with  int &r = i; ; this is called binding a reference to an object
  • You do not need to dereference a reference to access the variable’s value:
  • To make sure the arguments are passed by reference in a method:
  • On the other hand, the same method using pointers must be passed the variables by reference in the call:

Managed instances

Instances of managed objects should be used through handles ( ^ , also called “hat”). It can be read “is a handle to the instance of the managed class”. Then, you use the handle as if it was the actual instance.

Note that, even though you don’t have to use managed objects in C++/CLI, you have to declare instances of managed objects with a handle.

Managed pointers

Because of garbage collection (which changes memory addresses), you can’t just use a regular C/C++ pointer to a managed objects. The managed pointers are called interior pointers. A good overview can be found here.

The syntax for interior pointers is very… declarative:

Native pointers are automatically converted to interior pointers (the inverse is not true):

As with pointers in C++, usage interior pointers is not recommended, and you should rather use managed references.

Managed references

A managed reference is called a tracking reference and uses  %  instead of & .

Managed pointers and references have some weirdness, for which this SO post goes into further details.

Further readings

C++/CLI wrapping a C library: cheatsheet

Because once in a while I write a C++/CLI wrapper around a C library, but since I do it so infrequently I forget everything each time. Here is a list of pointers (haha) for common pitfalls and problems.

Compiling and debugging

You have to wrap the .h into an #ifdef __cplusplus extern “C” :

You also need to remove the /clr option for C files.
Right click your C files > Properties > C/C++ > General > Common Language RunTime Support > No CLR Support.

In your managed class, to include an unmanaged C header, use managed(push|pop)

Because Linux and Windows get along so well, you may also have to redefine a few C methods in your header file.

If you wish to create a C# unit test project (using xUnit for instance), with Visual Studio 2012 and later, you will have to do a few things:

  • In the C++/CLI project’s properties, in Debugging, choose the Debugger Type “Mixed”
  • In the Visual Studio options, Debugging, check “Managed C++ Compatibility Mode” (in VS2012) / “Use Managed Compatibility Mode” (in VS2013).

To build using MSBuild, you may have to change the toolset to VS2012: project properties > General > Platform Toolset = Visual Studio 2012 (v110). And set the Configuration Type to Dynamic Library (.dll) while you’re at it.

Managed and unmanaged objects

gcnew instantiates a managed objects, which will be garbage collected. Always use it for the managed objects.

To easily call the native structures through managed classes, use the internal constructor and ToNative methods.

Powershell for data mining Access databases into SQL Server

I need to do some data extraction from several hundreds of Access databases extracted from zip files. The extracted data will allow us to do some statistics on our customer’s behavior.
In order to do that, I decided to use Powershell, because it has all the features I need, bundled in one neat language.

The scaffolding for the scripts uses PSake for the task launcher, Pester for Powershell unit tests, and a few Nuget packages (including PSake).

In a vendor folder, add the Nuget exe, as well as a packages.config file listing the necessary Nuget packages. I have added PSake, and NUnitOrange to transform the Pester results to a nice HTML report.
I’m not using the Pester Nuget package because it includes the Pester unit tests, and some of them fail, which breaks my build (in addition to adding a thousand tests I don’t care about). Instead, I directly include the Pester scripts, and I cleaned up the samples and tests.

Since the script needs to read Access databases using some sort of ADODB or OLEDB provider, you will have to install either the Access 2007 or Access 2010 provider. If you’re like me (with Office x86 already installed), you won’t be able to install the Access 2010 x64 provider, which will trigger “The Jet/ACE OLEDB provider is not registered on the local machine” errors. So you will have to run the x86 version of Powershell. Which means you will have to use the x86 version of the SQLPS module (make sure you download the x86 version). Don’t worry, the SQL 2012 version of SQLPS is compatible with older SQL Servers (at least 2008 R2).

The batch bootstrapper is inspired by the bootstrapper from Pester:

The tasks in tasks.ps1 are pretty standard and minimalist, so that the maximum is tested in modules via Pester.

Reading Access databases is as simple as using OleDb, old-school style:

And the corresponding Pester tests, using actual Access test databases:

Executing SQL scripts uses the much more powerful Invoke-SqlCmd cmdlet from the SQLPS module. The most is that it returns a Powershell object, so I can do something like this: