Level Up with Pluralsight – Learn FREE for All April

Just a heads up to let you know that Pluralsight is making all video courses FREE for the month of April!

Are you interested in getting started with the C programming language?

What about getting to know some practical features of C++14 and C++17?

Do you need a practical introduction on how to use the C++ Standard Library’s containers (like std::vector, std::list, std::map, std::unordered_map, etc.)?

Would you like an introduction to data structures and algorithms in C++?

Or would you like to learn modern C++ from scratch?

All these courses of mine and 7,000+ other courses are available for FREE for all April!

Level up your tech skills for free all month long. Click the banner below to access Pluralsight #FreeApril!

The Case of string_view and the Magic String

Someone was working on modernizing some legacy C++ code. The code base contained a function like this:

void DoSomething(const char* name)

The DoSomething function takes a read-only string expressed using a C-style string pointer: remember, this is a legacy C++ code base.

For the sake of this discussion, suppose that DoSomething contains some simple C++ code that invokes a C-interface API, like this (of course, the code would be more complex in a real code base):

void DoSomething(const char* name) 

SomeCApi also expects a “const char*” that represents a read-only string parameter.

However, note that the SomeCApi cannot be modified (think of it like a system C-interface API, for example: a Windows C API like MessageBox).

For the sake of this discussion, suppose that SomeCApi just prints out its string parameter, like this:

void SomeCApi(const char* name) 
    printf(“Hello, %s!\n”, name);

In the spirit of modernizing the legacy C++ code base, the maintainer decides to change the prototype of DoSomething, stepping up from “const char*” to std::string_view:

// Was: void DoSomething(const char* name)
void DoSomething(std::string_view name)

The SomeCApi still expects a const char*. Remember that you cannot change the SomeCApi interface.

So, the maintainer needs to update the body of DoSomething accordingly, invoking string_view::data to access the underlying character array:

void DoSomething(std::string_view name) 
    // Was: SomeCApi(name);

In fact, std::string_view::data returns a pointer to the underlying character array.

The code compiles fine. And the maintainer is very happy about this string_view modernization!


Then, the code is executed for testing, with a string_view name containing “Connie”. The expected output would be:

“Hello, Connie!”

But, instead, the following string is printed out:

“Hello, Connie is learning C++!”

Wow! Where does the “ is learning C++” part come from??

Is there some magic string hidden inside string_view?

As a sanity check, the maintainer simply prints out the string_view variable:

// name is a std::string_view
std::cout << “Name: “ << name;

And the output is as expected: “Name: Connie”.

So, it seems that cout does print the correct string_view name.

But, somehow, when the string_view is passed deep down to a legacy C API, some string “magic” happens, showing some additional characters after “Connie”.

What’s going on here??

Figuring Out the Bug

Well, the key here are two words: Null Terminator.

In fact, the C API that takes a const char* expected the string to be null-terminated.

On the other hand, std::string_view does not guarantee null-termination!

So, consider a string_view that “views” only a portion of a string, like this:

std::string str = “Connie is learning C++”;
auto untilFirstSpace = str.find(‘ ‘);
std::string_view name{str.data(), untilFirstSpace}; // “Connie”

The string_view certainly “views” the “Connie” part. But, if you consider the memory layout, after these “Connie” characters in memory there is no null terminator, which was expected by the C API. So, the C API views the whole initial string, until it finds the null terminator.

So, the whole string is printed out by the C API, not just the part observed by the string_view.

Memory layout: string_view vs. C-style null-terminated strings
Memory layout: string_view vs. C-style null-terminated strings

This is a very subtle bug, that can be hard to spot in more complex code bases.

So, remember: std::string_views are not guaranteed to be null terminated! Take that into consideration when calling C-interface APIs, that expect C-style null-terminated strings.

P.S. As a side note, std::string::c_str guarantees that the returned pointer points to a null-terminated character array.

Repro Code

// The Case of string_view and the Magic String 
// -- by Giovanni Dicanio

#include <stdio.h>

#include <iostream>
#include <string>
#include <string_view>

void SomeCApi(const char* name)
    printf("Hello, %s!\n", name);

void DoSomething(std::string_view name)

int main()
    std::string msg = "Connie is learning C++";
    auto untilFirstSpace = msg.find(' ');

    std::string_view v{ msg.data(), untilFirstSpace };

    std::cout << "String view: " << v << '\n';


New Pluralsight Course on Getting Started with the C Language


My new Pluralsight course on Getting Started with the C Language is LIVE!

In this course you’ll learn in a practical way, with a combination of slides and demo code, the basic aspects of the C programming language and tools, so that you can start being productive with the C language.

Starting from this course page, you can freely play the course overview, and read a more detailed course description and the table of content.

Some of the major topics include: understanding the role of the C compiler, and compiling from both the command line and using an IDE; learning about common basic types and basic I/O; learning the syntax for decision making in C (e.g. the if-else and switch statements) and how to write loops (e.g. for, while and do-while); the basics of working with strings; learning how to write your own functions. Pointers will be introduced, as well.

I’ll also show some subtle C beginner’s bugs, I will analyze them and discuss how to fix them.

Inspecting the content of a C string.
Inspecting the content of a C string.
Discussing the memory layout of strings in C.
Discussing the memory layout of strings in C.
Analyzing a subtle bug.
Analyzing a subtle bug.
Introducing pointers in C.

These are some feedback notes from my reviewers:

The content is presented with great clarity and is organized effectively. Great module. [Peer Review]

I really like that your demos are very concise and tightly focused on the syntax and concepts you’re explaining. There’s nothing extra to cause confusion. Well done! [Peer Review]

Your code slides are well-designed and easy to read. [Peer Review]

I REALLY like that you explained the potential problem with […]. I wish more people would heed the advice you present here. [Peer Review]

Very clean module with clear explanations and demos. Great job! [Peer Review]

Happy learning!


Pluralsight Black Friday 40% Off

Just wanted to give you all a heads up about current Pluralsight Black Friday 40% Off promotion on all Personal Annual and Premium subscriptions.

Click on the banner below to save now.

The Case of the Context-Menu Shell Extension That Doesn’t Get Invoked by Explorer

A developer was working on a context-menu shell extension.

He wrote all the skeleton infrastructure code, including some code to display the selected files when the shell extension gets invoked by Windows Explorer. It’s kind of the “Hello World” for context-menu shell extensions.

He happily builds his code within Visual Studio, copies the shell extension DLL to a virtual machine, registers the extension in the VM, right-clicks on a bunch of files… but nothing happens. His extension’s menu items just don’t show up in the Explorer context-menu.

What’s going wrong, he thought?

He starts thinking to all sorts of hypotheses and troubleshooting strategies.

He once again manually registers the COM DLL that implements the shell extension from the Command Prompt:

regsvr32 CoolContextMenuExtension.dll

A message box pops up, informing him that the registration has succeeded.

He tries right-clicking some files, but, once again, his extension’s menu items don’t show up.

He then checks that the extension was properly registered under the list of approved shell extensions (this was part of his shell extension infrastructure C++ code):

HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Shell Extensions\Approved

He finds the GUID of the shell extension in there, as expected.

He then checks that the extension was registered under the proper subkey in HKEY_CLASSES_ROOT. Found it there, too!

He starts wondering… what may be going so wrong?

He checks the C++ infrastructure code generated by the ATL Visual Studio wizard, including his own additions and modifications. The implementations of DllRegisterServer and DllUnregisterServer seem correct.

He also checks his own C++ code in the C++ class that implements the shell extension’s COM object. He has correctly implemented IShellExtInit::Initialize, and the three methods of IContextMenu: GetCommandString, InvokeCommand, and QueryContextMenu.

He takes a look at the class inheritance list: both IShellExtInit and IContextMenu are listed among the base classes.

The IShellExtInit and IContextMenu COM interfaces are correctly listed among the base classes.
The IShellExtInit and IContextMenu COM interfaces are correctly listed among the base classes.

He feels desperate. What’s going wrong?? He wrote several shell extensions in C++ in the past. Maybe there’s some bug in the current version of Visual Studio 2019 he is using?

Why wasn’t his context-menu shell extension getting called by Explorer?


I took a look at that code.

At some point, I was enlightened.

I gave a look at the COM interface map in the header file of the C++ shell extension class.

There’s a bug in the shell extension C++ object’s COM interface map.
There’s a bug in the shell extension C++ object’s COM interface map.

Wow! Can you spot the error?

Something is missing in there!

In fact, in addition to deriving the C++ shell extension class from IContextMenu, you also have to add an entry for IContextMenu in the COM map!

I quickly added the missing line:


The COM interface map, with both the IShellExtInit and IContextMenu entries.
The COM interface map, with both the IShellExtInit and IContextMenu entries.

I rebuilt the extension, registered it, and, with great pleasure and satisfaction, the new custom items in the Explorer’s context-menu showed up! And, after selecting a bunch of files to test the extension, the message box invoked by the shell extension C++ code was correctly shown.

All right! 😊

So, what was going wrong under the hood?

Basically, since the context-menu shell extension was correctly registered under the proper key in the Windows Registry, I think that Windows Explorer was actually trying to invoke the shell extension’s methods.

In particular, I think Explorer called QueryInterface on the shell extension’s COM object, to get a pointer to IContextMenu. But, since IContextMenu was missing from the COM map, the QueryInterface code implemented by the ATL framework was unable to return the interface pointer back to Explorer. As a consequence of that, Explorer didn’t recognize the extension as a valid context-menu extension (despite the extension being correctly registered in the Windows Registry), and didn’t even call the IShellExtInit::Initialize method (that was actually available, as IShellExtInit had its own entry correctly listed in the COM map from the beginning).

The bug is in the details!

So, the moral of the story is to always check the COM map in addition to the base class list in your shell extension’s C++ class header file. The COM interfaces need to both be in the base class list and have their own entries in the COM map.

And, in addition, to me this experience has suggested that it would have been great if Visual Studio had issued at least a warning for having the IContextMenu COM interface listed among the base classes, but missing from the COM map! This would be an excellent time-and-bug-saving addition, Visual Studio IDE/Visual C++/Visual Assist X teams!


Where Should I Register My Context-Menu Shell Extension to Operate on All Files and Folders?

A developer was working on a context-menu shell extension. He registered the extension under:


The developer noted that his context-menu extension was called for all files. But he also wanted his extension to be called for all directories.

If you want your context-menu shell extension to be invoked on all files and all file folders, the correct key to use for registration is HKCR\AllFileSystemObjects, not HKCR\*.

For more information, MSDN has a list of Predefined Shell Objects.


Simplifying Windows Registry Programming with the C++ WinReg Library

The native Windows Registry API is a C-interface API, that is low-level and kind of hard and cumbersome to use.

For example, suppose that you simply want to read a string value under a given key. You would end up writing code like this:

Sample code excerpt to read a string value from the Windows Registry using the native Windows API.
Sample code excerpt to read a string value from the Windows Registry using the native Windows API.

And this is just the part to query the destination string length. Then, you need to allocate a string object with proper size (and pay attention to proper size-in-bytes-to-size-in-wchar_ts conversion!), and after that you can finally read the actual string value into the local string object.

That’s definitely a lot of bug-prone C++ code, and this is just to query a string value!

Moreover, in modern C++ code you should prefer using nice higher-level resource manager classes with automatic resource cleanup, instead of raw HKEY handles.

Fortunately, it’s possible to hide that kind of complex and bug-prone code in a nice C++ library, that offers a much more programmer-friendly interface. This is basically what my C++ WinReg library does.

You can query a string value with just one simple line of C++ code using WinReg.
You can query a string value with just one simple line of C++ code using WinReg.

WinReg is an open-source C++ library, available on GitHub. For the sake of convenience, I packaged and distribute it as a header-only library, which is also available via the vcpkg package manager.

If you need to access the Windows Registry from your C++ code, you may want to give C++ WinReg a try.