Pluralsight FREE Weekend!

Just a heads up to let you know that Pluralsight is opening up its platform with thousands of video courses for the entire weekend (November 18th-20th).

This means that you can watch all the courses you want for free during this weekend!

Are you interested in getting started with the C language? Or do you want to learn about Data Structures and Algorithms in C++?

All my courses, as well as all the existing courses, are available for free during this weekend.

Don’t miss this opportunity!

Happy learning!

How To Suppress Spurious Warnings with Visual C++?

I was working on some Windows C++ code with Visual C++ 2019, and I got the following warning:

Warning C6387:

‘utf16’ could be ‘0’:  this does not adhere to the specification for the function ‘std::basic_string_view<wchar_t,std::char_traits<wchar_t> >::{ctor}’.

Spurious warning C6837 with Visual C++ 2019

In general, I compile my C++ code at warning level 4 (/W4), as I like to have the C++ compiler speak up when it detects something that looks wrong to it.

However, in this case I was right and the C++ compiler (code analyzer) was wrong.

In fact, in this particular case, the code analyzer was saying that I had a const wchar_t* utf16 pointer, that could be potentially null (“utf16 could be 0”), and I was passing it to a wstring_view constructor overload that does not expect null pointers.

What the code analyzer did not figure out is that I already checked for the special case of the null pointer value in the if statement just above!

if (detail::IsNullOrEmpty(utf16))
{
    return std::string{};
}

So, if the utf16 pointer passed the if check, the wstring_view constructor would have certainly received a non-null pointer value.

 

So, once you are sure that your code is correct and the C++ compiler is wrong, how do you suppress such spurious warnings?

Well, you could think of using a #pragma warning (disable) directive, like this:

// Disable the warning C6387
#pragma warning( disable: 6387 )

The problem with this approach is that you end up disabling that warning for all the following code that gets processed by the C++ compiler, potentially muting warning messages that are legit, and could help you spot subtle bugs!

So, what you really want to do is to locally disable the warning, for the specific line (or lines) of code that you are sure is correct, and then immediately re-enable it for the next code.

To do that, you can use this kind of #pragma push-disable-pop dance:

// Save the current warning state
#pragma warning( push )

// Disable the warning locally for just the following code
#pragma warning( disable : 6387 )

// Code that is processed with the above warning disabled

// Re-enable the previous warning state
#pragma warning( pop )

In addition, for a case like the one discussed here, where you just want to temporarily disable a warning for a single line of code, you can use the shortcut #pragma warning (suppress) directive, like this:

#pragma warning( suppress: 6387 )

// Just one line of code for which the warning is suppressed

For the sake of clarity and code maintainability, I usually like to add a comment block, specifying additional information about the compiler version I’m using and the warning number and message, and why I think that that warning is spurious. So, when the same code is compiled with an updated compiler version that is smarter and doesn’t detect the spurious warning anymore, I can completely remove the #pragma warning(suppress) directive.

 

Pluralsight 33% OFF PROMO

Did you enjoy the recent one-week-only free Pluralsight library offer?

Now it’s a great time to subscribe to Pluralsight, as there’s a 33% off promo currently active.

Click the banner below and save now!

Convenient Unicode UTF-8 UTF-16 Conversion Functions for Windows C++ Code

I published on GitHub a header-only library (Utf8Conv) that implements some convenient functions to convert text between UTF-8 and UTF-16 Unicode encodings.

I developed the library using Visual Studio 2019 with C++17 features enabled.

The library is very easy to use. Once you have included the library header Utf8Conv.hpp, you can simply invoke its functions like this:

#include "Utf8Conv.hpp" // Library header

// Note: Library functions live under the Utf8Conv namespace.

...

// Convert from UTF-8 to UTF-16
wstring utf16String = Utf8ToUtf16(utf8String);

// Convert from UTF-16 to UTF-8
string utf8String = Utf16ToUtf8(utf16String);

The input strings can be expressed via std::[w]string objects, and also using std::[w]string_views as well.

The returned strings are always instances of std::string for UTF-8-encoded text and std::wstring for UTF-16 text.

Enjoy!

 

Pluralsight FREE Week!

In case you didn’t know, Pluralsight is unlocking their technology skills platform and making 7,000+ expert-led video courses, 40+ interactive courses and 20+ projects free for one week only!

Learn as much as you can, end enjoy this Pluralsight FREE Week!

C++14-Compatible WinReg

I got several requests by people asking to make my C++ WinReg code (which has been using C++17 in its main branch since many months) compile on older C++14 compilers (like VS 2017 in C++14 mode).

Now you can find the C++14-compatible version in this branch.

To make the code C++14-compatible, among other things, I removed the use of [[nodiscard]], removed std::variant (simply substituted with a couple of data members), and replaced the non-const std::wstring::data() method with &s[0].

 

Exceptions or Error Return Codes?

In the initial version of my WinReg C++ library, I made a design decision that methods that wrapped Win32 Registry C API calls would throw C++ exceptions on errors.

Important feedback I got from the users of this library was that they wanted methods that returned error codes instead of throwing exceptions (e.g., see this issue).

For example, when opening a registry key, folks want to be able to check the result of the operation without having exceptions thrown from failed opens. Similarly when trying to read values from the registry.

This is a good remainder for those C++ devs who think that we should always throw exceptions instead of using error return codes!