Debugging in Visual Studio 2017 with a Command Line Compiled (cl.exe) and Linked (link.exe) Debug Executable Example

Compile (cl.exe) with /Zi /Od /Fd

Link (link.exe) with /DEBUG /DEBUGTYPE:PDATA

The produced executables will contain the full path in the Dynamically Linked Libraries (DLLs) and Executables.

To debug in Visual Studio 2017 go to File > Open Project/Solution… and select your executable.

Advertisements

In C++ when should I use std::endl versus “\n”?

I see so many people confused about the use of “std::endl” versus “\n”, so here I explain when they should be used…

std::endl

The use of std::endl will insert an end of line character.

It will also flush the pipe in which it is used on! This is important to know and I will explain why below.

“\n”

The use of “\n” will insert an end of line character.

When should I use each?

It depends on your use case, but generally you should use “\n”, unless you need to flush the buffer for some reason.

When should I flush the buffer?

When you write to a standardized stream the output is buffered and then after some X number of chars or other special events (e.g. std::endl, std::flush) the buffer is flushed and all data is written to the stream.

Using this built-in buffer helps speed up your program as writing to these streams can be very slow, especially if you are going to disk. However, if you can minimize how often you write to the stream and instead write in large bursts less often then the overall program will run faster (hence the purpose of buffering streams).

However, if the program exits and unflushed buffers exist, then they are not guaranteed to be flushed before termination.

You have probably seen this behavior when some messages weren’t appearing even though you knew you had hit a line of code that wrote to that stream. This is also why some streams (e.g. std::cerr) are completely unbuffered.

If you write an error message to a buffered pipe and then throw an exception, it is unlikely that the error message will be printed before the program exits. This is why error messaging pipes are configured (by default) to be unbuffered.

For streaming to disk

If you are calling std::endl for every line you stream to disk, then you are making your program unnecessarily slow and hammering the disk IO (maybe even network IO) which is very inefficient.

While you certainly shouldn’t flush every line you write to disk, it is important to flush the buffer to disk once you are done writing to it.

For writing to a display

Like I mentioned early std::cerr (STDERR) is unbuffered, but std::cout (STDOUT) is buffered.

If you want to call std::endl when writing to std::cout to guarantee that those lines are printed in case the program exits then you can do that, but make sure you have good justification for writing to std::cout. Seeing as std::cerr is unbuffered, you should ask yourself if std::cerr is a better fit for your use-case?

You can use flush lines you write to std::cout (STDOUT), but it is inefficient. The  std::cerr (STDERR) stream is unbuffered and was designed for this purpose, so consider using it instead.

In C++ how do I use regex to replace a string match

In C++11 the regex library was added which allows you to do regex directly:

#include <string>
#include <regex>
...
std::string workingOn("this text string\n");

std::regex expressionStart("^th");
std::string removed = std::regex_replace(workingOn, expressionStart,"");
// removed will contain "is text string"

std::regex expressionReplace("\\bte([^ ]*)");
// match word beginning with 'te' and grab everything to the end of it
// which will be stored in $1 as the first captured match
std::string replaced = std::regex_replace(workingOn, expressionReplace,"ve$1");
// replaced will contain "this vext string"

Also to search and capture just the matches:

std::smatch matches;

// Match will contain: 1:Full string match, 2: Major, 3: Minor
std::regex e("^Release ([1-9][0-9]*)");

std::string number;

// Matches represent one match in the regex, but has all of the sub patterns
// etc. and thus there are multiple matches for a single regex match...
while (std::regex_search(test, matches, e)) {
  //matchingLine = matches[0];
  number = matches[1];
  break;
}
std::cout << "Number: " << number << std::endl;

vim find a line that has this but not that

To find lines which have “This” and “NotThat” it is as simple as:

:g/This\&\(.*NotThat\)\@!

Let’s dive into each piece of this in a little more detail…

The :g is a way to list out all matches in a file. For instance to see all lines listed out which match “This” you could use:

:g/This

Furthermore, if you wanted lines that contained both “This” and “That” then you could use:

:g/This\&\(.*That\)

The reason why the .* is needed is that it looks for the conjoined match (the ampersand) from the previous match. You will notice that the highlighting/match will select the range, i.e.

we use brackets to show the match from [This to That] nothing else matches

By adding the \@! we tell vim to negate that term and viola we are search for “This” and not “That” e.g.

:g/This\&\(.*That\)\@!

Would match the second line, but not the first:

we use brackets to show the match from This to That nothing else matches
on this line we only have This and thus it will match

Notice that only the second line will match.

Using rpm to find an installed program (RedHat, CentOS, Fedora)

To see what programs are installed use:

rpm -qa

If you just installed a program and want to know where it went then grep for it:

$ rpm -qa | grep vim-X11
vim-X11-7.4.160-2.el7.x86_64

Once you have the name of the package, then you can list the files it installed:

$ rpm -ql vim-X11-7.4.160-2.el7.x86_64
/usr/bin/evim
/usr/bin/gex
/usr/bin/gview
/usr/bin/gvim
/usr/bin/gvimdiff
/usr/bin/gvimtutor
/usr/bin/vimx
/usr/share/applications/gvim.desktop
/usr/share/icons/hicolor/16x16/apps/gvim.png
/usr/share/icons/hicolor/32x32/apps/gvim.png
/usr/share/icons/hicolor/48x48/apps/gvim.png
/usr/share/icons/hicolor/64x64/apps/gvim.png
/usr/share/man/man1/evim.1.gz

There is my gvim I was looking for.

P.S. If these newly installed executables aren’t working from PATH, then try opening a fresh shell.

Vim finding and replacing without captures

Normally when doing find and replaces in a file there are some key words that we want to key off, but not replace. This can be a pain because you have to then isolate the part you want to change, capture everything but the changing part, and then reconstruct it in the substitution. Well there is a better way…

If your goal is to prepend all of the name=”bad-.*” with name=”good-.*”, then we would normally have to write something like:

:s/\(name="\)bad\(-.*"\)/\1good\2/g

There is a better way using zoom start ‘\zs’ and zoom end ‘\ze’:

:s/name="\zsbad\ze-/good/g

Happy finding and replacing!

 

Vim Highlighting

I highlight my searches in VIM using the following in my .vimrc:

" Highlight search terms...
set hlsearch
set incsearch " ...dynamically as they are typed.
nmap  n :silent :nohlsearch
" stop highlighting with n

While demoing or in a code review it is nice to highlight more than one item. You can use searching to match multiple words:

/term1\|term2

Note: You can also us CTRL+R followed by a ‘/’ to paste the exact last search term

However, it is also nice to do highlights in different colors – or to keep a highlight persistent while you search for other terms. To do this I use:

:match Search /pattern/

Now this will use the same highlight color as normal search. You can replace Search, the name of the highlight group, with another group to highlight with a different color (tab completion works here).

To disable the highlighting from match use:

:match none

Enjoy highlighting!