CS 12 - Lab 1


CS 12 Homepage
Welcome to CS 12 labs. In this course, all programming will be done under the Linux operating system, using standard programming tools for that environment. Linux is a free operating system, available for all to download (RH) (Mandrake) and use with no cost. Linux itself is about a decade old, but in conjunction with a set of free utilities from the GNU project, behaves like a member of the UNIX family of operating systems. UNIX has been the standard for research institutions and the computer industry in general for decades. As a matter of pride it is expected that you, as a Computer Science student, will learn to use it. To help you toward this end, there will be no usage of Windows during lab sections for CS12, nor will any assistance be given to students wanting information on moving/recompiling their assignments completed originally under Windows. It is very much in your best interest to get used to Linux as early as possible, since it will be your primary tool for Computer Science for the rest of your term here at UCR. Tutorials on Linux are available all over the Internet, Google for "Linux tutorial" and find one that suits you, or just try this one.

In this lab, we will be doing three things:

Introduction to Linux

Linux can be used with a Graphical User Interface much like Windows, but also has an extremely powerful and all-encompassing command line interface that allows you to interact more quickly and efficiently with the system. To access this interface, click on the icon that looks like a black computer monitor. This will pop up a window known as a "Terminal." Inside your terminal window is where you enter your commands.

Basic Commands There are literally hundreds of additional commands commonly available, as well as a large number of options available for the commands presented here. It is highly recommended that you take some time to experiment with these commands, read some documentation, and get to know your environment. With more than 25 years of history, nearly everything you might want to do has been done and automated by some other developer and included in the plethora of UNIX commands. Learning as many as you can will make your life later on easier and easier. Start early.

Editing Files
There are many many options for editing text files under Linux. The two most common are emacs and vi. Emacs is somewhat easier for beginners, so we will focus on using emacs in this course. We recommend that you experiment with other editors to find the one that suits you best.

To invoke emacs, simply type emacs in a terminal window and press Enter. Examine the menus on your own. If you have any questions, ask your TA or search for help on Google.

Sending/Receiving Email
There are a vast number of options for reading your email under Linux, ranging in features and complexity from Evolution (a program that presents an interface similar to that of many common Windows email programs) to "mail" (the offspring of one of the first email clients.) We will focus on using pine, a common UNIX mail reader. To invoke it, you must be connected to the CS Department server, hill.cs.ucr.edu. First type "ssh hill" in a terminal window, and type your password. Once logged in, type "pine" on the command line (in a terminal window). If you are running pine for the first time, hit "Enter" to inform the makers of pine that you are using it (so they can estimate the number of users).

Play with pine on your own, and ask questions if you have any. Try sending yourself an email message, and make sure that you can read it.

g++

The very popular (and free!) compiler for UNIX systems is gcc. When used to compile C++ programs, it is generally invoked as g++. Throughout this course we will be using g++ for compilation. In its simplest invocation, we only need to call it with the name of the program we are trying to compile. In this example we will compile "hello.cc". (Note that the standard filename extension for C++ files is now ".cc" rather than ".cpp").

Here we will try to compile the following:
hello.cc - first attempt:
#include <iostream.h>

void main()
{
    cout << "Hello World!" << endl;
}
Now we save that file (in emacs), and try to compile in the terminal.
> g++ hello.cc
In file included from /usr/include/c++/3.2/backward/iostream.h:31,
                 from hello.cc:1:
/usr/include/c++/3.2/backward/backward_warning.h:32:2: warning:
#warning This file includes at least one deprecated or antiquated
header. Please consider using one of the 32 headers found in section
17.4.1.2 of the C++ standard. Examples include substituting the <x>
header for the <x.h> header for C++ includes, or <sstream> instead of
the deprecated header <strstream.h> . To disable this warning use
-Wno-deprecated. 
hello.cc:6: `main' must return `int'
Sadly, our program failed to compile, and g++ produced a lot of (somewhat) mysterious output when we tried to compile it. Let's look more closely at what happened:
In file included from /usr/include/c++/3.2/backward/iostream.h:31,
                 from hello.cc:1:
/usr/include/c++/3.2/backward/backward_warning.h:32:2: warning:
#warning This file includes at least one deprecated or antiquated
header. Please consider using one of the 32 headers found in section
17.4.1.2 of the C++ standard. Examples include substituting the <x>
header for the <x.h> header for C++ includes, or <sstream> instead of
the deprecated header <strstream.h> . To disable this warning use
-Wno-deprecated. 
Is really just one long warning (note at the end of the third line there it says "warning"). What this really means, in very complicated language, is that we should not have had "iostream.h", but rather "iostream", the new standard. (Those of you that took CS 10 last quarter are probably aware of this.) Now let's look at the second bit of output
hello.cc:6 `main' must return `int'
Unlike Microsoft's version of C++, g++ enforces the standard practice of having the main function be of type "int." This is fairly easy to fix. Now let's see where we are: hello.cc - version 1:
#include <iostream>

int main()
{
    cout << "Hello World!" << endl;
}
Gives us the following output:
> g++ hello.cc
hello.cc: In function `int main()':
hello.cc:5: `cout' undeclared (first use this function)
hello.cc:5: (Each undeclared identifier is reported only once for each function
   it appears in.)
hello.cc:5: `endl' undeclared (first use this function)
What? "cout" undeclared? Did we lose the ability to print things to the screen when we moved from Windows to Linux?

Of course not. g++ enforces the new C++ spec regarding namespaces. The namespace issue is a bit compilcated for this course, but as last quarter's CS10 students can attest, this problem can be solved in one of two ways:
#include <iostream>

int main()
{
    std::cout << "Hello World!" << std::endl;
}
or
#include <iostream>

using namespace std;

int main()
{
    cout << "Hello World!" << endl;
}
Stylistically, it is probably best to get into the habit of using the first method.

Regardless of your choice on this issue, let us see if this fixes our simple program:
> g++ hello.cc
>
Nothing happens. Believe it or not, this is a good thing. (A rule of thumb under UNIX is that if no output was generated, everything worked correctly.) However, we still have not run our program. When compiling, g++ creates executable files named "a.out" by default. If you don't like this default choice (and who does?), then you can add the "-o" command line parameter to pick your own filename, like this
> g++ hello.cc -o hello
(Note also that unlike Windows, no ".exe" extension is needed.) Now we have a file called "hello" in our current directory that when executed will (presumably) print out our friendly greeting.
> ./hello
Hello World!

>
It worked! You may be asking "Why do we have the ./ before the hello?" This is a good question, but requires a fairly lengthy explaination. Check the mailing list archive for the answer, it was answered during July 2003.

At this point you should be able to use g++ from the command line to compile a C++ program. However, to help you through some of the complicated concepts that will come up in this course, we are going to enforce the use of four additional options when compiling "-W", "-pedantic", "-Wall" and "-Werror".

-W is an option (also called a flag) for g++ that is given to the program on the command-line. It says, "I'd like you to warn me about all of the simple mistakes that people might make." This lets g++ do some of the checking for you that would otherwise cause you lots of time and trouble. (Remember, warnings that are caught are often logic errors that you don't have to fight! This is a very good thing.)

-pedantic means that g++ will turn off some of the features in the g++ compiler that are not part of the C++ standard. For the most part these are fairly esoteric, but there are a couple common things that people in this course would do with g++ that are not actually allowed by the standard, so we enforce this flag in an effort to prevent you from learning non-standard (bad) habits.

-Wall says "If I do anything in this program that is really odd, warn me." C++ has a long long list of things that could possibly indicate a programming mistake, but by default many of them are not checked when compiling. Adding -Wall ensures that many of the more complex things it can warn you about will be reported. (It is like having a very picky set of eyes checking over your program for you. This is a good thing.)

-Werror is related to the other flags in that they all deal with warnings. Unlike the others, it doesn't enable additional warning messages. Instead -Werror tells the compiler "If you ever feel like warning me about anything, consider that an error and do not compile any further." This way even if you wanted to ignore the warnings, you would have to find a way to convince the compiler that you really know what you are doing. We are enforcing the use of these to flags so that your programs are more likely to work on complicated input, and because there really is no reason to have any warnings in a well written program. For your home programming projects, we will compile your submissions with -Wall and -Werror, so you should get used to using them now.

So the general command line you will be using this quarter when compiling by hand is:
> g++ -W -Wall -Werror -pedantic myprog.cc -o myprog
You probably want to memorize this.

Assignment

4 points possible
We want to ensure that everyone has at least experimented with the basic Linux commands presented here. Follow these directions to prove that you understand the command line: As you go, copy the contents of your terminal window into your original Emacs window "lab1.txt". (Note: To copy and paste under Linux, simply highlight what you want to copy, and then hit the middle mouse button to paste.) When you are done, save that file and close Emacs.

3 points possible
Write a program in C++ that reads its input a single-character at a time and prints out the numeric value of that character. Repeat until there is no more input to read (for a note on how to do this, check here). For a table of the correct values (so you can check your work), try the man page for the word "ascii".

Sample execution:
> ./numchar
a
97
$
36
~
126
^D
>

Miscellaneous Tasks

1.2 points possible
When you are all finished, explore your Linux environment, the history of Linux / UNIX, or other related things online. Attendance for the full lab period is mandatory. Try working on some of the following short tasks. To receive credit, add these to the top of your "lab1.txt" file. Each task is worth 0.2 points, out of 10 possible. If you finish with all of this, you can either browse around for information on Linux / UNIX, more shell commands, or more information on Emacs or any of the other text editors available under Linux - the opportunities are endless!!

Lab Grading

Attendance - 2 points
Terminal session turned in - 7 points
Misc. Tasks - 1 point
Extra credit - .2 points
Total: 10.2/10

© 2004 UC Riverside Department of Computer Science & Engineering. All rights reserved.