c++11 - Tomato Soup https://www.wholetomato.com/blog Visual Assist Team Blog Thu, 11 Apr 2024 18:04:41 +0000 en-US hourly 1 https://wordpress.org/?v=6.4.5 https://i0.wp.com/www.wholetomato.com/blog/wp-content/uploads/2020/05/cropped-wt-logo.jpg?fit=32%2C32&ssl=1 c++11 - Tomato Soup https://www.wholetomato.com/blog 32 32 227787260 Visual Assist 2023.6 release post https://www.wholetomato.com/blog/2023/11/28/va-2023-6-release/ https://www.wholetomato.com/blog/2023/11/28/va-2023-6-release/#respond Tue, 28 Nov 2023 06:58:29 +0000 https://blog.wholetomato.com/?p=3637 Visual Assist 2023.6 is here and is available to download! This release is filled to the brim with new functionality that improves upon your staple VA features and a new, convenient way to share source...

The post Visual Assist 2023.6 release post first appeared on Tomato Soup.

]]>
Visual Assist 2023.6 is here and is available to download! This release is filled to the brim with new functionality that improves upon your staple VA features and a new, convenient way to share source code with colleagues.

We also have a new code checker, support for two new C++ language features, and small but useful improvements to VA’s behavior. Read on further to get the complete details of the changes and improvements in this release, or download the release right away.

Share source code via email, GitHub, and more.

Starting from VA 2023.6, users can now highlight sections of code from the editor and open the Quick Actions and Refactoring (Shift + Alt + Q) menu, or right-click on the code and select the “Share with team member” option to instantly send code to other developers.

Select and share sections of code by highlighting it and using the Quick Actions
menu (Shift + Alt + Q).

Choose where and how you want to share your code. This new feature can work in conjunction with GitHub Gist and GitLab’s snippets feature, where you can instantly share and upload parts of your source code. You can also send your source code via email for more general-use purposes. 

Improvements to VA’s navigation features

This release provides a number of improvements and additional functionality to VA’s bread and butter navigation features, such as open file in solution and find symbol in solution.

  • Fuzzy search and uppercase search for opening files and searching symbols
    Fuzzy search is a technique used in searches and information retrieval to find approximate matches for a given query, accommodating variations like typos and misspellings. It employs string distance metrics to measure the similarity between strings.

    Visual Assist’s open file in solution and find symbol in solution will now employ this algorithm, so you can expect more results with fewer, less accurate search queries.

    Furthermore, besides fuzzy searching for inexact matches, VA will also match capital letters. If you have a class named MyClassName, searching for “mcn” would find it. It works similarly if you have a global variable named myGlobalVariable and type “mgv”. It is smart enough to count the lowercase “my” as if it were MyGlobalVariable leading to expected results.

    Enable fuzzy search and see smarter search results using approximate string matching.

     

     

  • Select all items in open file in solution (Ctrl + A)
    You can now select and highlight multiple files and open them simultaneously when using open file in solution. The usual shortcut Ctrl + A works.

    Select and open all files with the new select all shortcut.

Improved support for Braced Initialization Lists / Uniform initialization (C++ 11)

2023.6 also improves support for braced initialization of lists and/or uniform initialization. Brace initialization lists and uniform initialization provide a more consistent and flexible way to initialize objects in C++. 

These features  improve code readability and reduce the chances of certain types of errors. Visual Assist’s parser will recognize these lists and highlight and suggest auto corrections within them.

Improved support for constexpr, consteval and constinit  (C++ 20)

These features are related to compile-time evaluation and initialization. They have specific use cases and are used to enforce certain behaviors at compile time. If you haven’t been using these, here’s a quick breakdown:

  • constexpr used to indicate that a function or variable can be evaluated at compile time.
  • consteval a stricter version, ensuring that the function or expression is only evaluated at compile time and cannot be evaluated at runtime.
  • constinit is used to indicate that a variable must be initialized at compile time and, once initialized, its value cannot be changed during the program’s lifetime.

When using these features, Visual Assist will recognize what you are trying to accomplish such as refactoring commands mainly. Refactorings such as Create From Usage will now properly handle these keywords.

New code inspection for detecting “magic-numbers”

This new Clang-based code inspection checks for instances of magic numbers—or numeric literals that are used without any definition—that are advised against by many coding guidelines for readability sake.

Enable code inspections by navigating to Extensions ->> VAssistX ->> Code Inspection ->> Enable code inspections.  This specific code inspection is disabled by default because some users may be intentionally using it and are not interested in “fixing” it.

Then you can either click on detected issues underlined in blue, use the Quick Refactoring Menu (Shift + Alt + Q) while on the highlighted issue, to allow VA to do it for you. In this case, there is no automatic fix so it will prompt you to define a variable with that number as its value and use the variable instead. 

Protip: VA can help do that for you with the introduce variable feature. If you highlight the number, then use the Quick Actions menu and select Introduce Variable it will ask you for a name and pull the number out into a variable for you.

You can read more about the readability-magic-numbers code checker on Clang’s documentation

New move class feature

You can now move entire classes into different files with the new move class feature included in 2023.6. 

For example, if you have a class named MyClass, with its declaration in MyClass.h and its definition in MyClass.cpp, you can move the entire class into a new pair of files, MyClassNew.h and MyClassNew.cpp. 

This is useful if you have a header and source file pair (.h and .cpp) that contain multiple classes and you want to break that up into multiple files.

Bug fixes and improvements

For this release, we have a couple of fixes based on user requests. The most notable of these improvements include a fix for file exclusion instructions using .json configs similar to a previous release, a parser improvement for Unreal Engine 5, and improved auto-detect logic for Unity.

  • Fixed multiple issues with file exclusion logic when reading from “.vscode\settings.json” configs.  
  • Our parser now better understands Unreal Engine 5.0 (specifically that build) types, such as FVector.
  • Fixed Create from Usage behavior when used inside const inline methods. 
  • Fixed coloring of [[fallthrough]] marked enum items. 
  • Attempted to fix rare temporary hang when debugging C# Unity projects.
  • Code Inspections options dialog now displays much more quickly. 
  • Improved Unity engine auto detect logic to reduce false positives.

Thanks to those who submitted their feedback and bug reports. Please continue sending them our way. Send us a message or start a thread on the user forums for bug reports or suggestions.

You can also check our download page to manually update to the latest release. Happy coding!

 

 

The post Visual Assist 2023.6 release post first appeared on Tomato Soup.

]]>
https://www.wholetomato.com/blog/2023/11/28/va-2023-6-release/feed/ 0 3637
Summer CodeFest: Magnificent or Malevolent: Maps! Measured, Monitored, & Magnified! [Mrecap] https://www.wholetomato.com/blog/2023/08/27/summer-codefest-magnificent-or-malevolent-maps-measured-monitored-magnified-mrecap/ https://www.wholetomato.com/blog/2023/08/27/summer-codefest-magnificent-or-malevolent-maps-measured-monitored-magnified-mrecap/#respond Sun, 27 Aug 2023 13:42:03 +0000 https://blog.wholetomato.com/?p=3380 Webinar overview:  Std::maps is a staple in the C++ world for sure. It’s reliable and useful, but in this presentation, David Millington goes a level deeper and examines how other features offered beyond the standard...

The post Summer CodeFest: Magnificent or Malevolent: Maps! Measured, Monitored, & Magnified! [Mrecap] first appeared on Tomato Soup.

]]>
Webinar overview: 

Std::maps is a staple in the C++ world for sure. It’s reliable and useful, but in this presentation, David Millington goes a level deeper and examines how other features offered beyond the standard library can be used to maximize the usefulness of the data structure. 

Quick Refresher on Maps

Maps are essentially a way to store key-value pairs in an ordered structure. This creates an associative array that can be used to lookup connected pieces of data. Maps are ubiquitous. Value-key lookup is used everywhere: filenames to files, index number to row/column, ID number to name, and the list goes on. 

Maps can be ordered or unordered. They are also similar to static arrays and vectors but they possess a few key differences such as memory management, performance, and appropriate types—watch this section of the webinar to learn more.

Things to Remember from the Webinar

 

Slide Deck Presentation

Replay

The post Summer CodeFest: Magnificent or Malevolent: Maps! Measured, Monitored, & Magnified! [Mrecap] first appeared on Tomato Soup.

]]>
https://www.wholetomato.com/blog/2023/08/27/summer-codefest-magnificent-or-malevolent-maps-measured-monitored-magnified-mrecap/feed/ 0 3380
How To Modernize With Visual Assist Part 2 https://www.wholetomato.com/blog/2021/04/01/how-to-modernize-with-visual-assist-part-2/ https://www.wholetomato.com/blog/2021/04/01/how-to-modernize-with-visual-assist-part-2/#respond Thu, 01 Apr 2021 04:51:56 +0000 https://blog.wholetomato.com/?p=1917 In the previous article, you read about five popular techniques to improve your projects and apply several Modern C++ patterns. Here’s a list of five more things! We’ll go from the override keyword to nullptr,...

The post How To Modernize With Visual Assist Part 2 first appeared on Tomato Soup.

]]>
In the previous article, you read about five popular techniques to improve your projects and apply several Modern C++ patterns. Here’s a list of five more things! We’ll go from the override keyword to nullptr, scoped enums, and more. All techniques are super-easy with Visual Assist!

1. Override

Let’s have a look at the following code with a simple class hierarchy:

using BmpData = std::vector<int>;

class BaseBrush {
public:
virtual ~BaseBrush() = default;

virtual bool Generate() = 0;

virtual BmpData ApplyFilter(const std::string&) { return BmpData{}; }
};

class PBrush : public BaseBrush {
public:
PBrush() = default;

bool Generate() { return true; }

BmpData ApplyFilter(const std::string& filterName) {
std::cout << "applying filter: " << filterName;
return BmpData{};
}

private:
BmpData m_data;
};

When you run VA code inspections, you’ll immediately see that it complains about not using the override keyword on those two virtual methods.

image1

In short, the override keyword allows us to explicitly specify that a given member function overrides a function from a base class. It’s a new keyword available since C++11.

As you might already know, you can go to VA Code Inspection Results and apply the fixes automatically. You’ll get the following code:

class PBrush : public BaseBrush {
public:
PBrush() = default;

bool Generate() override;

BmpData ApplyFilter(const std::string& filterName) override;
private:
BmpData m_data;
};

What are the benefits of using override?

The most significant advantage is that we can now easily catch mismatches between the virtual base function and its override. When you have even a slight difference in the declaration, then the virtual polymorphism will might not work. 

Another critical point is code expressiveness. With override, it’s effortless to read what the function is supposed to do.

And another one is being more modern as this keyword is also available in other languages like C#, Visual Basic, Java, and Delphi.

2. nullptr

When I work with legacy code, my Visual Assist Code Inspection Result is often filled with lots of the following items:

image3

This often happens with code like:

if (pInput == NULL) {
    LOG(Error, "input is null!")
    return;
}

or

pObject->Generate("image.bmp", NULL, NULL, 32);

Why does Visual Assist complain about the code? It’s because NULL is just a define and means only 0, so it doesn’t mean a null pointer, but it means 0. This is also a problem when you have code like:

int func(int param);
int func(float* data);
if you call:
func(NULL);

You could expect that the function with the pointer should be called, but it’s not. That’s why it’s often a guideline in C or early C++ that suggests not making function overrides with pointers and integral types.

The solution? Just use nullptr from C++11.

nullptr is not 0, but it has a distinct type nullptr_t.

Now when you write:

func(nullptr);

you can expect the proper function invocation. The version with func(float* data) will be invoked.

Not to mention that nullptr is a separate keyword in C++, so it stands out from the regular code. Sometimes NULL is displayed in a different color, but sometimes it is not.

Visual Assist makes it super easy to apply the fix, and it’s a very safe change.

3. Convert enum to scoped enum

Another pattern that is enhanced with Modern C++ is a way you can define enums.

It was popular to write the following code:

enum ActionType {
    atNone,
    atProcess,
    atRemove,
    atAdd
};

ActionType action = atNone;
Since C++11 it's better to you can define this type in the following way:
enum class ActionType {
    None,
    Process,
    Remove,
    Add
};

ActionType action = ActionType::None;

What are the benefits of such transformations?

  • They don’t pollute the global namespace. As you may have noticed, it was often necessary to add various prefixes so the names wouldn’t clash. That’s why you see atNone. But in the scoped enum version, we can write None.
  • You get strong typing, and the compiler will warn when you want to convert into some integral value accidentally.
  • You can forward scope enums and thus save some file dependencies.

What’s best about Visual Assist is that it has a separate tool to convert unscoped enums to enum classes, all with proper renames and changes in all places where this particular type was used. Right-click on the type and select “Convert Unscoped Enum to Scoped Enum.”. This opens a preview window where you can see and select which references will be replaced.

image2

Read more in Convert Unscoped Enum to Scoped Enum in the VA documentation.

4. Use more auto

One of the key characteristics of Modern C++ is shorter and more expressive code. You saw one example where we converted from for loops with long names for iterators into a nice and compact range-based for loops.

What’s more, we can also apply shorter syntax to regular variables thanks to automatic type deduction. In C++11, we have a “reused” keyword auto for that.

Have a look:

std::vector<int> vec { 1, 2, 3, 4, 5, 6, 7, 8};
std::vector<int>::const_iterator cit = vec.cbegin();

We can now replace it with:

std::vector<int> vec { 1, 2, 3, 4, 5, 6, 7, 8};
auto cit = vec.cbegin();

Previously, template-type deduction worked only for functions, but now it’s enabled for variables. It’s similar to the following code:

template <typename T> func(T cit) {
    // use cit...
}
std::vector<int> vec { 1, 2, 3, 4, 5, 6, 7, 8};
func(vec.cbegin()); // template deduction here!

Following are some other examples:

auto counter = 0;   // deduced int
auto factor = 42.5; // deduces double
auto start = myVector.begin(); // deduces iterator type
auto& ref = counter; // reference to int
auto ptr = &factor;  // a pointer to double
auto myPtr = std::make_unique<int>(42);
auto lam = [](int x) { return x*x; };

Have a look at the last line above. Without auto, it wouldn’t be possible to name a type of a lambda expression as it’s only known to the compiler and generated uniquely.

What do you get by using auto?

  • Much shorter code, especially for types with long names
  • Auto variables must always be initialized, so you cannot write unsafe code in that regard
  • Helps with refactoring when you want to change types
  • Helps with avoiding unwanted conversions

As for other features, you’re also covered by Visual Assist, which can automatically apply auto. In many places, you’ll see the following suggestions:

image5

This often happens in places like

SomeLongClassName* pDowncasted = static_cast<SomeLongClassName*>(pBtrToBase); 
// no need to write SomeLongClassName twice:
auto pDonwcasted = static_cast<SomeLongClassName*>(pBtrToBase);

or

unsigned int val = static_cast<unsigned int>(some_computation / factor);
// just use:
auto val = static_cast<unsigned int>(some_computation / factor);

As you can see, thanks to auto, we get shorter code and, in most cases, more comfortable to read. If you think that auto hides a type name for you, you can hover on it, and the Visual Studio will show you that name. Additionally, things like “go to definition” from Visual Assist work regularly.

5. Deprecated functionality

With C++11, a lot of functionality was marked as deprecated and was removed in C++17. Visual Assist helps with conversion to new types and functions.

For example, it’s now considered unsafe to use random_shuffle as it internally relied on simple rand(), which is very limited as a random function generator.

std::vector<int> vec { 1, 2, 3, 4, 5, 6, 7, 8 };
std::random_shuffle(vec.begin(), vec.end());

Visual Assist can replace the above code with the following:

std::shuffle(vec.begin(), vec.end(), std::mt19937(std::random_device()()));

Additionally, you’ll get suggestions to improve old C-style headers and convert them into C++ style:

image4

Some other handy fixes

We have covered a few inspections, but there’s much more! Here are some exciting items that you might want to see:

The whole list is available here: List of Code Inspections

Summary

Thanks for reading our small series on Clang Tidy, Code Inspections, and Visual Assist. We covered a lot of items, and I hope you learned something new. The techniques I presented in most cases are very easy to use, especially thanks to VA support, and you can gradually refactor your code into Modern C++.

https://www.wholetomato.com/downloads

 

The post How To Modernize With Visual Assist Part 2 first appeared on Tomato Soup.

]]>
https://www.wholetomato.com/blog/2021/04/01/how-to-modernize-with-visual-assist-part-2/feed/ 0 1917
How to Modernize C++ Code with Visual Assist in Five Easy Steps https://www.wholetomato.com/blog/2021/03/11/how-to-modernize-c-code-with-visual-assist-in-five-easy-steps/ https://www.wholetomato.com/blog/2021/03/11/how-to-modernize-c-code-with-visual-assist-in-five-easy-steps/#respond Thu, 11 Mar 2021 22:45:22 +0000 https://blog.wholetomato.com/?p=1842 You probably know that over time our projects seem to get old and legacy. Code written now might look suspicious five years later. With the standardization of C++11 in 2011, developers coined the term Modern...

The post How to Modernize C++ Code with Visual Assist in Five Easy Steps first appeared on Tomato Soup.

]]>
You probably know that over time our projects seem to get old and legacy. Code written now might look suspicious five years later. With the standardization of C++11 in 2011, developers coined the term Modern C++. In this article (and the next one) we’ll take a look at some techniques you might apply to get nicer code and be closer to the best feature that recent versions of C++ offer. 

Let’s start! 

1. Rename and Aim for Meaningful Names You might be surprised by the first point on our list. 

Is rename added to C++11 as a feature? 

No, it’s definitely not just an element of C++. In fact, having good names is not a feature of any programming language, as it depends on your style. The compiler can take any names, including single letters and even almost any Unicode character. Thanks to better IDE support and powerful text editors, we can now avoid shortcuts and rely on full and meaningful names. 

And what’s most important is that we can leverage extra refactoring tools, like those from Visual Assist, to fix code with the legacy style. 

Let’s have a look at the following class: 

class PBrush { 
public: 
	PBrush(); 
	~PBrush(); 

	bool Gen(HDC r) { } 
	bool IsAval() const { return aval; } 

private: 
	bool aval; 
	
	HGLOBAL m_hGlobal; 
	LPBITMAPINFO lpBitmap; 
	LPBYTE lpBits; 
	HDC ReferenceDC; 
	
	RGBQUAD m_pal[256]; 
}; 

Read the above code and think about potential naming issues. Is the code clear and descriptive? What would you change? 

Or take a look at the following function, which uses this PBrush objects: 

std::vector<PBrush*> FilterAvalBrushes(const std::vector<PBrush*>& brs) { std::vector<PBrush*> o;
	ULONG totalBCount = 0; 
	size_t totalBitmaps = 0; 
	
	for (size_t i = 0; i < brs.size(); ++i) { 
		if (brs[i]->IsAval()) { 
			o.push_back(brs[i]); 
			++totalBitmaps; 
			totalBCount += brs[i]->GetByteCount(); 
		} 
	} 
	
	// make sure they have some bits ready: 
	for (size_t i = 0; i < o.size(); ++i) { 
		if (!o[i]->Bits()) 
			Log("ERROR, empty bitmap!"); 
	} 
	
	Log("Byte count %d, total bitmaps %d", totalBCount, totalBitmaps); return o; 
}

How could we improve the code? 

You might be tempted to say that it’s better to leave old code and not touch it since other systems might depend on it. However, adding or changing to better names and keeping it useful to other systems is very simple. In most cases, you can find and replace old names or use Rename from Visual Assist. 

Visual Assist has a powerful feature for renaming objects and making sure the code compiles after this transformation. It was also one of the earliest VA features and enabled using this refactoring capability years before Visual Studio added it. 

You can invoke the rename tool in many situations. 

The simplest way is to hit a key shortcut when your cursor is inside a particular name ( Shift + Alt + R by default). For example, let’s say that I’d like to rename bool aval, so I move my cursor there and invoke the dialog, and then I can see the following window: 

Another option is to write a new name, and then VA will show a handy context menu where you can invoke the rename or see the preview window before making the changes. 

What other things can you do with rename? 

Improve consistency of names. For example, your style guide might suggest adding m_ before each nonstatic data member for classes. So you might quickly improve it and add this prefix for classes that don’t share this style. In our example, some names start with m_ while others don’t. 

It’s not only variables and functions but also things like enumerations and namespaces. 

But most importantly, what name would be better for aval? Do you prefer m_isAvailable ? or Available ? I’ll leave it as an exercise. 

2. Extract Smaller Functions 

Here’s another example to fix: 

// number of data components 
switch ( format ) 
{ 
case GL_RGB: 
case GL_BGR_EXT: components = 3; break; 
case GL_RGBA: 
case GL_BGRA_EXT: components = 4; break; 
case GL_LUMINANCE: components = 1; break; 
default: components = 1; 
} 

GLuint t; 
glGenTextures(1, &t); 

// load data 
HBITMAP hBmp = (HBITMAP)LoadImage(NULL, fname, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE | LR_CREATEDIBSECTION); 
if (hBmp == NULL) 
	return 0; 
	
// rest of code... long code

The above code is just a part of some longer function that loads, opens a file, loads bytes, and creates an OpenGL texture object with the loaded data. One thing that we might immediately do is to make this function smaller. More compact functions are easier to read and allow for more code reuse.  We can see that it has several smaller subtasks, so it would be better to extract them into separate parts. For example, we can implement FormatToComponents

And when you select this context menu, you’ll get the following dialog: 

After some adjustments (for example, we don’t need to take components as input argument), we can prepare the following code: 

int FormatToComponents(GLenum format) { 
	switch (format) { 
	case GL_RGB: 
	case GL_BGR_EXT: return 3; 
	case GL_RGBA: 
	case GL_BGRA_EXT: return 4; 
	case GL_LUMINANCE: return 1; 
	} 
	return 1; 
} 

And then call it from our initial function: 

GLuint LoadTextureFromBmp(const char *fname, GLenum format, GLuint filter) { const int components 
	= FormatToComponents(format);  

This not only gave us shorter, cleaner code, but also we can now mark our variable as const, which even improves the quality. Additionally, this function might be reused in some other places of the system. 

Here are the general rules for the extraction by VA: 

Symbols available globally, or within the class of the original and new methods, are not passed via a parameter list. 

Symbols used only in the right side of expressions (i.e., not modified) are passed by value. Symbols used in the left side of expressions (i.e., assigned) are passed by reference. Symbols referenced with dot notation within the extracted code (e.g., classes and structs) are always passed by reference. 

When a newly created method assigns a value to only one symbol, that symbol is passed by value and the assignment is done in the original method via return value. 

Symbols local to extracted code become local to the new method; they are not passed.

 3. Improve Function Interfaces 

Let’s now challenge ourselves with this one: 

bool Init2d(HDC hdcContext, FontMode fm, HFONT hFont, GLuint iWidth, GLuint iHeigth, GLuint iTexture, bool forceBold, bool forceItalic, size_t numGlyphs); 

It’s a member function in GLFont that is responsible for creating a texture font from a Window font. We can later use this created object to draw text in an OpenGL application. 

Isn’t it worrying that this function takes nine input arguments? 

And here’s an even more suspicious-looking call site: 

glFont.Init2d(const_cast<CGLApp *>(glApp)->GetHdc(), fmBitmap, hFont, iWidth, iHeight, 0, false, false, 256);

Some books suggest that if you have more than 5… or 7, then it’s some worrying code smell.  Such long lists of function arguments are hard to read, and caller sites might easily put them in a wrong order. Another issue is that there are a few boolean parameters, and it’s hard to see what they mean from the caller perspective. 

You can use Change Signature to modify all parts of a signature, including: 

  • Method name 
  • Return type 
  • Visibility 
  • Parameter names 
  • Parameter types 
  • Parameter order 
  • Number of parameters 
  • Qualifiers 

The plan for our function is to introduce a structure that would hold all parameters. We can do it by simply copying the parameter list and putting it into a structure above the function declaration: 

struct FontCreationParams { 
	GLuint iWidth; 
	GLuint iHeigth; 
	GLuint iTexture { 0 }; 
	bool forceBold { false}; 
	bool forceItalic { false}; 
	size_t numGlyphs { 256 }; 
}; 

As you can see, I even assigned some default values. 

And then we can change the signature in two steps: 

1. Add new argument to the function: const FontCreationParams& param with a default value of TODO. 

2. And then, again remove those extra arguments. 

Then you might compile code and fix call sites. 

The final code might look as follows: 

FontCreationParams params; 
params.iWidth = iWidth; 
params.iHeigth = iHeight; 
glFont.Init2d(const_cast<CGLApp *>(glApp)->GetHdc(), fmBitmap, hFont, params);

With this approach, if you need some more parameters (or you need to alter them), it’s just a matter of modifying the structure, and the function declaration will be the same. 

While you can do such a change manually, Visual Assist makes it much more comfortable and takes care of most of the cases at the call site. So this significantly simplifies and automates the process when you have many function calls. 

So far, we discussed basic principles for code modernization, but how about automation? Can we use extra tools that would tell us what to change in our code? 

Let’s see the fourth point. 

4. Enable Code Inspections 

Since a few years ago, Visual Assist has come with code Inspections that automatically check your code and pinpoint any issues. 

Code Inspection analyzes C/C++ for specific code quality issues as you edit. The feature, based on LLVM/Clang, warns you of issues in your code and if possible, suggests and applies quick fixes. 

You can enable them via Settings or as shown below: 

You can read the full description of Inspections in the excellent documentation website Introduction to Code Inspection and also see our previous article where we dive a bit deeper A Brief Introduction to Clang-Tidy and Its Role in Visual Assist – Tomato Soup. 

Currently,  we have almost 30 code inspections, and the number grows with each revision: List of Code Inspections. 

They range from checking .empty() vs size() , using emplace_back(), nullptr usages, and many more. They can help not only with code modernization but even with finding some performance issues in code. It’s like a small code analysis run on the code. 

Let’s  take a look at one related to for loops. 

5. Make For-Loops More Compact 

One of the coolest elements of C++11 style comes from using simpler for loops. This is especially important for code that uses containers from the Standard Library. 

For example, before C++11, you had to write: 

std::vector { }... 
for (std::vector<int>::iterator it = vec.begin(); it != vec.end(); ++it) std::cout << *it << '\n'; 

Now, this can be simplified with this simple syntax: 

std::vector<int> vec { 1, 2, 3, 4, 5, 6 }; 
for (const auto& elem : vec) 
	std::cout << elem << '\n';

Why not automate this transformation? 

VA identifies places where you can use this modern syntax and then rewrites loops for you. 

Consider this example: 

std::vector<PBrush*> FilterAvalBrushes(const std::vector<PBrush*>& brushes) { // ... 
	for (size_t i = 0; i < brushes.size(); ++i) { 
		if (brushes[i]->IsAval()) { 
			out.push_back(brushes[i]); 
			++totalBitmaps; 
		} 
	} 
} 

When code inspections are enabled, we can see the following suggestions:

What’s nice about Visual Assist is that it’s very smart and tries to deduce the correct loop syntax. 

For example, when our vector holds pointers, then the converted loop is as follows: 

std::vector<PBrush*> FilterAvalBrushes(const std::vector<PBrush*>& brushes) { // ... 
	for (auto brushe : brushes) { 
		if (brushe->IsAval()) { 
			out.push_back(brushe); 
			++totalBitmaps; 
			totalBCount += brushe->GetByteCount(); 
		} 
	} 
} 

But when we change the type into const std::vector<PBrush> (so it holds not pointer but “full” objects), then the loop is as follows: 

for (const auto & brushe : brushes) { 
	if (brushe.IsAval()) { 
		out.push_back(brushe); 
		++totalBitmaps; 
		totalBCount += brushe.GetByteCount(); 
	} 
}

The system is smart and avoids situations where you’d copy objects during loop iteration, as it’s more efficient to use references. 

That’s just a taste of what you can automatically do with Visual Assist and its code inspections! 

Summary 

In this article, you’ve seen five suggestions on how to check and improve your code. We started with something fundamental but often skipped: naming. Then we made functions smaller and with better interfaces. And at the end, we enabled code inspections so that Visual Assist can automatically identify more things to repair. 

In the last item, we looked at loop transformation, which is available from C++11. Thanks to Visual Assist, we can automate this task and quickly modernize our code to the newer standard 

After such refactoring, we aim to have safer, more readable code. What’s more, with more expressive code, we can help the compiler to identify potential errors. This is just a start, and stay tuned for the next article where you’ll see other code modernization techniques: override keyword, nullptr, enum class, auto type deduction, and deprecated headers.

The post How to Modernize C++ Code with Visual Assist in Five Easy Steps first appeared on Tomato Soup.

]]>
https://www.wholetomato.com/blog/2021/03/11/how-to-modernize-c-code-with-visual-assist-in-five-easy-steps/feed/ 0 1842