C++ Accelerated Massive Parallelism: Digest

C++ AMP is coming with Visual Studio 2011. Here are information and good articles introducing it:

Herb Sutter: Heterogeneous Computing and C++ AMP

MSDN overview page

PDF: “C++ AMP : Language and Programming Model” – the specification

A list of articles:





Notes about improving your Visual C++ debugging skill

Good Start Point

One useful link to start: PDB Files: What Every Developer Must Know

Summary from the blog article:

1) PDB files are as important as source code!

2) Every development shop must set up a Symbol Server.

Other useful things

Microsoft Windows Symbol Server is introduced here.

Source Server A tool to further facilitate debugging public build.

Symbol Proxy Advanced tool to give you centralised symbol store and performance boost on debugging. 


Unnecessary relink caused by “/DYNAMICBASE” in Visual C++ 2008

I am working on a big C++ solution which includes many DLL and EXE projects. It is created before Visual C++ 2008. Now we migrate to VC 2008, and I create new DLL projects in the solution.

I find that everytime there is change in my new DLL code, no matter how trivial it is, for example, only comment change in .cpp file, all dependent projects relink. It happens on my new projects, not those existing projects. So I spent some time comparing project settings, and found the cause:

/DYNAMICBASE (Use address space layout randomization)

By default, /DYNAMICBASE is on.

This option modifies the header of an executable to indicate whether the application should be randomly rebased at load time.

Address space layout randomization is supported on Windows Vista.

There is also another technical article from MSDN blog:

Address Space Layout Randomization in Windows Vista

This is a new program security enhancement setting introduced in VC 2008. It causes compiled binary to change everytime. Switching this setting off makes problem gone.

If your solution is big and you don’t need this level of security, switch it off for all your new projects.

MFC GetParentFrame() returns NULL

I write this little post to record a small fact that you may have to pay attention to when you create your new CView inside your CFrameWnd.

By default, when you use Visual Studio’s resource editor to add a new dialog template for your CView class, the window style of that dialog template includes WS_POPUP. This normally doesn’t crash your program. However, we may want to call GetParentFrame() function within our CView from time to time, and if WS_POPUP is present, the function will return NULL pointer, causing memory access violation exception.

So, whenever you create CView within a frame window, pay attention to window style given by Visual Studio, and change WS_POPUP to WS_CHILD if needed.

Custom drawing selected item rows in Windows List-View Control

This is code snippet to demonstrate how I redraw subitems in selected item rows in List-View Control. Although MFC is rarely used in GUI development today, I record code solution here for the benefit of minority.

Background is that, Windows Common Control provides generic way to let us do custom drawing, that is to handle custom draw in notification handler of NM_CUSTOMDRAW. (See http://msdn.microsoft.com/en-us/library/bb761817(v=vs.85).aspx)

However, in List-View control, when item’s state is “selected”, that item is always white text in blue background. Custom draw code can’t override the effect. To solve this problem, we have to do entire custom drawing in the message handler. In case CDDS_ITEMPREPAINT, instead of passing drawing to subitem stage CDDS_SUBITEM | CDDS_ITEMPREPAINT, we return CDRF_SKIPDEFAULT, and draw entire item manually.

		// lplvcd is pointer to NMLVCUSTOMDRAW structure
		int itemIndex = lplvcd->nmcd.dwItemSpec;

		// Can't use (lplvcd->nmcd.uItemState | CDIS_SELECTED) to tell whether item is selected
		// when List-View control has style LVS_SHOWSELALWAYS.
		// See http://msdn.microsoft.com/en-us/library/bb775483(v=vs.85).aspx
		UINT selectState = GetItemState(itemIndex, LVIS_SELECTED);
		if (selectState == LVIS_SELECTED)
			CDC dc;
			if (dc.Attach(lplvcd->nmcd.hdc))
				DrawSelectedItem(dc, itemIndex);
void CMyListCtrl::DrawSelectedItem( CDC& dc, int nIndex )
	int subitemCount = GetHeaderCtrl().GetItemCount();
	CRect itemRect;
	for (int i = 0; i < subitemCount; i++)
		if (i == 0)
			CalculateItemRect(nIndex, itemRect);
		else if (!GetSubItemRect(nIndex, i, LVIR_BOUNDS, itemRect))

		// Adjust text rect to not overlap with grid lne and leave some space
		itemRect.DeflateRect(6, 0);
		dc.DrawText(GetItemText(nIndex, i), itemRect, DT_LEFT | DT_NOCLIP | DT_VCENTER | DT_SINGLELINE | DT_END_ELLIPSIS);

void CMyListCtrl::CalculateItemRect( int nIndex, CRect& rect )
	// Calculate item head subitem(index = 0) rect
	// GetSubItemRect() returns rect of entire row for subitem 0
	if (GetSubItemRect(nIndex, 0, LVIR_BOUNDS, rect))
		CRect nextRect;
		if (GetSubItemRect(nIndex, 1, LVIR_BOUNDS, nextRect))
			rect.right = nextRect.left;

C++ Standard Notes – Program Execution

C++ Standard (Draft n3126)

Program Execution (1.9)

Context of this section is single-thread execution. Single-thread execution environment consists of full-expressions.

1. Full-expression

A full-expression is an expression that is not a subexpression of another expression.
Normally a full-expression is a single line of C++ code that ends with ‘;’, or expression in conditional clause like “if”, “while”. In contrast, a subexpression is always part of a full-expression.

If a language construct is defined to produce an implicit call of a function, a use of the language construct is considered to be an expression for the purposes of this definition.
For example, call of casting operator, or class constructor function.

A call to a destructor generated at the end of the lifetime of an object other than a temporary object is an implicit full-expression.
This means normal implicit destructor call is full expression. A temporary object may be created and destroyed, in situation like function argument value computation. In this case, destructor call to the temporary object is subexpression.

Conversions applied to the result of an expression in order to satisfy the requirements of the language construct in which the expression appears are also considered to be part of the full-expression.
This includes glvalue-to-prvalue conversion, array-to-pointer conversion, and so on.

2. Evaluation of expression

Evaluation of an expression (or a sub-expression) in general includes both value computations and initiation of side effects.
Side effect itself is not part of evaluation of expression. Side effect can be understood as any action that changes memory content or triggers external I/O.

The execution of unsequenced evaluations can overlap.
How to understand this? Because every evaluation can be translated into multiple assembly codes, assembly codes from unsequenced evaluations can interleave.

Except where noted, evaluations of operands of individual operators and of subexpressions of individual expressions are unsequenced.(1) The value computations of the operands of an operator are sequenced before the value computation of the result of the operator.(2) If a side effect on a scalar object is unsequenced relative to either another side effect on the same scalar object or a value computation using the value of the same scalar object, the behavior is undefined.(3)
We can understand this by understanding example given below it:

void f(int, int);
void g(int i, int* v) {
	i = v[i++]; // the behavior is undefined
	// It is undefined because of statement (3). On right side of assignment, i++ has side effect of modifying i, and i is also used in subscripting expression(5.2.1) v[...].

	i = 7, i++, i++; // i becomes 9
	// This is equivalently (i = 7), i++, i++. It is well-formed because comma operator(5.18) is sequenced from left to right.

	i = i++ + 1; // the behavior is undefined
	// It is undefined because of statement (3). This is same as first example, because subscripting operator is essentially pointer + integral type.

	i = i + 1; // the value of i is incremented
	// It is well-formed. No side effect.

	f(i = -1, i = -1); // the behavior is undefined
	// It is undefined because of statement (1) and (3). But behaviour is expected in reality because both side effects assign -1 to i.

Link below is a thread discussion about why behaviour of i = v[i++] is undefined:

In my opinion, the reasoning there is overkilling and sometimes wrong.