CS585 Visual Studio TutorialUsing a Graphical Integrated Development Environment (IDE) can be a bit of an adjustment if you are used to command line tools and debugging with output statements. It is worth the time you will spend overcoming the learning curve because it will make you more efficient at developing, debugging, and testing your code. The following tutorial walks through some of the basic features for getting started with Visual Studio 2012, in conjunction with the first lab, available on the CS585 website.
Compiling and Running
Standard Out and Working Directory
Debugging with Breakpoints and Watch Variables
Changing the Default Project
Command line Arguments
More Stepping and Debugging
Cleaning Your Solution Before Submitting
Common Errors in C++ and What They Mean
The first time Visual Studio runs, it will ask you what language you want to use so it can set itself up properly. Choose C++ and then click the button that says "Start Visual Studio".
In Visual Studio, a "Project" (.vcxproj) is sort of like a Makefile because it knows about all of the different files that need to be compiled together to make an executable. It also contains extra information about any extra include paths or library files needed to compile. In general, each project is associated with exactly one executable (or sometimes a DLL or other entity).
A "Solution" (.sln) is a collection of projects that are related in some way. If you would like to have multiple executables together in the same Visual Studio entity, a solution is how you do it. It is sort of like having several different build targets in a Makefile.
In the skeleton code for the first lab, there are four projects: One for each of the three parts of the lab and another for the skeleton of the first programming assignment. Below, you see a screen shot of my solution open in Visual Studio. On the left, there is the list of projects and their associated code. On the right, top, there is the editor panel, and on the right, bottom is the output window where any errors are displayed.
Visual Studio's convention is that the solution file will be at the top level directory, and will contain one folder for each project. Inside of the folder for the project, there will be the project file and any associated code.
In Visual Studio, for some reason line numbers are not displayed by default. To turn them on, go to the "TOOLS" menu, then select the "Options" menu item. In the Options Dialog, under "Text Editor", "All Languages", "General" there is a check box to turn on line numbers.
Unlike emacs, Visual Studio does not automatically indent your code for you. Fortunately, you can tell Visual Studio to indent your code for you if things get too messy by going to the "EDIT" menu, selecting the "Advanced" menu sub-menu, then choosing the "Format Selection" or "Format Document" menu items. The keyboard shortcut is Ctrl K, Ctrl F
Compiling and Running
There are several ways to compile and run a project in Visual Studio. The easiest way is to press F5, which will direct Visual Studio to attempt to compile your code, and then run it (as long as the compilation is successful).
Below, I show two ways of just compiling the code for a project. First, you can right click on the project, then go to Build. The second way is to go to the BUILD menu item at the top of the window, then go down to "Build Lab1_Part0". (You can also build all of the projects in the entire solution by choosing "Build Solution.")
Below, I show three ways of running your code. Whenever you attempt to run a project, if the code has changed since you last compiled, Visual Studio will prompt you to ask if you want to recompile.
The first, and easiest, way to run your code is to find the little green triangle next to the words "Local Windows Debugger". The second way is to go to the DEBUG menu and choose the "Start Debugging" item. Both of these ways of running your project will run the **default project** in the solution (the one marked with bold on the left panel. We will discuss how to change this a little later.
The last way to run your code is the right click on the project you want to run, then go down to "Debug" then choose "Start new instance."
If you have a longer program that is taking a while to run, there are two ways to stop it before it is finished. The easiest way is to press the Stop button, which is a little unlabeled button with a red square. The other way to stop it is to go to the DEBUG menu, then choose the menu item "Stop Debugging."
Standard Out and Working Directory
When your code is running, you may want to display some output to the terminal. In C++, this is done with the cout command. Output is displayed in a black terminal window that will appear when you run your program.
The present working directory is the folder containing the project file. All relative paths are specified with respect to the working directory. The image read in by this program must be contained in the folder with the project, or the program will not be able to find it.
Debugging with breakpoints and watch variables
When many of us first learned to program, we learned that if we wanted to see the execution of the program, we should just print the values of all of our variables to the terminal. If we wanted to see something different, we changed the output that the program printed and then recompiled and ran again.
Setting break points in a program with a debugger allows you to stop the execution of a program so that you can examine as many variables as you want, and also understand how the state of the program changes as you step through the code. In Visual Studio, you set breakpoints in a program by clicking in the gray bar that runs on the left side of the editor window. A red circle will appear to show you the break point you created.
When you run your program, Visual Studio will stop execution of your program at the break point. A yellow arrow will appear in the gray sidebar so that you can see the current line that is about to be executed.
Once your program has stopped, you advance the execution of the program one line at a time using the "Step Over" (F10) and "Step Into" (F11) commands. These commands are represented as little icons with blue errors in the menu bar at the top of the window. Once you press this button, line of code will be executed and the little yellow arrow will move to the next line.
Most of the time, I recommend defaulting to use "Step Over" (Shortcut: F10), which runs the command on that line, but does not go inside the function. It can be very disorienting if you get dumped into the middle of a library function.
Once you have stopped in the debugger, you can then examine the contents of the variables that are defined in the current scope using a set of windows that will appear docked at the bottom of the main window. These sub-windows are called "Autos," "Locals," and "Watch 1." I find that the most useful window is "Watch 1," where you can type the names of the variables you want to see, as well as simple arithmetic expressions. The other window I like is the "Locals" window, which shows all of the variables in the current scope. In the "Autos" window, Visual Studio tries to be smart and guess what variables you might like to see based on the variables used in the surrounding code, but this makes me a little crazy. Variables that are modified by the previous line of code are highlighted in red.
After you have stopped, you may want to resume (continue) the flow of the program. This is done by either pressing F5, or pressing the Continue button, which is a little green triangle. This functionality may also be accessed by going to the "DEBUG" menu and choosing the "Continue" menu item.
Switching Projects within a Solution
Once you have finished with Part 0 of the first lab, you would like to switch to working on Part 1 of the lab. If you just want to compiled and run the code of Part 1, you can do that by right clicking on the project name and selecting either "Build" or "Debug" then "Start New Instance"
If you would like to switch over to working on Part 1 so that when you press F5, the Part 1 project will run automatically, then you need to change the default project in the solution. This is done by right clicking on the project name, then choosing the "Set as Startup Project" menu item.
Command line arguments
Instead of hard-coding filenames and thresholds, it is preferable to use command line arguments. To set command-line arguments in Visual Studio, right click on the project name, then go to Properties. In the Properties Pane, go to "Debugging", and in this pane is a line for "Command-line arguments." Add the values you would like to use on this line. They will be passed to the program via the argv array.
More stepping and debugging
In the second part of the lab, I have provided some functions to demonstrate moving through and manipulating image data with OpenCV. For this tutorial, I will just discuss the aspects of Visual Studio that allow you to control the flow of execution of the program.
We will begin by setting a break point at the line where our first function is called.
We run the program, and Visual Studio stops the flow of execution at the break point that we have set. At this point, we would like to examine the execution of this function. One way to do this either by setting a breakpoint within the function and pressing continue. Another way is to "Step Into" the function. This is done by pressing F11 or by pressing the icon with little blue arrow.
Pressing the "Step Into" button brings us to the start of the function. Once we are inside a function, we can use the "Call Stack" sub-window (lower right) to see where we are in the program (this can be useful if you have some sub-function that is called from many higher-level functions, and you would like to go to the calling function.)
We can then control the flow of the program as described above. Let's say that we would like to examine the state of a loop at some particular point, for example, when the index variable is equal to a certain value. First, we set a break point at where we would like to stop the flow of control. Second, we set up a condition on the break point by right-clicking on the break point, selecting the "Condition" menu item, and then typing the condition into the dialog. We then press continue to resume the program. Once the condition is satisfied, the debugger stops and we can examine the program state. Warning: setting a condition on a break point can make the program run very slowly.
If we would then like to allow the function to finish and then stop, without resuming the execution of the whole program, we can use the "Step Out" command. This will bring us back up to the calling function on the next line.
Cleaning Your Solution
As you work and set break points and compile, etc. Visual Studio creates a lot of temporary files to keep track of your work. These can be quite large, so before you submit, you should remove all of these temporary files by "Cleaning" your solution. This is done by going to the "BUILD" menu, and then choosing the "Clean Solution" menu item. Be sure to close Visual Studio before zipping up your work to submit. This should remove most of the other temporary files.
Common Errors in C++
One of the most frustrating things about learning a new language is learning how to translate from the compiler error messages into understanding what is actually wrong with the code. Below, I have created cartoon code snippets to illicit some common compiler errors. As a general rule, if you have a large list of errors, you should start with the first error in the list, which can generate many down stream errors even if nothing else is actually wrong.
First, I have inserted a compiler error into the code, and then attempted to compile the code by right clicking on the project and choosing the "Build" menu item.
Visual Studio displays many errors from compilation in the Output Window. By double-clicking on a specific error message, Visual Studio will place your cursor in the editor window and place a small black line in the gray sidebar on the offending line of code.
"syntax error : missing ';' before identifier"
In this classic error, you may have forgotten a semicolon at the end of a line of code (line 27.) Note that Visual Studio assigns the error to the ***next*** line of code (line 30), even though the actual error is on the line above (line 27).
"error C2065: 'missing Declaration' : undeclared indentifier"
Here, we have attempted to do something with a variable before defining it. To correct the error on line 27, we would insert the type before the name of the variable.
"error C2086 : 'int doubleDeclaration' : redefinition ... see declaration of 'doubleDeclaration'"
If you attempt to define a variable twice (Lines 27 and 28), this will give a compiler error. To fix this, you should delete one of the lines of code.
"error C2064: term does not evaluate to a function taking 0 arguments"
This somewhat cryptic error can happen if you accidentally try to treat a variable (or class member) as a function by using parentheses after its name (Line 30).
"error 3867 : ... : function call missing argument list"
This equally cryptic error message occurs when you treat a function (or class method) for a variable (or class member) and do not use parentheses after its name.
"error C2660: ... : function does not take 0 arguments"
If you invoke a function using parentheses, but you either forget the arguments or do not provide enough arguments, this is the error message you will see.
"error C2660: ... : function does not take 1 arguments"
If you invoke a function with the wrong number of arguments in general, this is the error message you will see
"error C2664: ... : cannot convert parameter 1 from int to const std::string& "
If you attempt to invoke a function with the correct number of arguments, but the arguments are of the wrong type, you will see this "cannot convert parameter" error message.