Department of Engineering

IT Services


Here are some answers to C++-related questions commonly asked at CUED. If you can think of questions that should be added here, mail Tim Love (tl136). A more comprehensive list of C++ Frequently Asked Questions is available, though it's not aimed at absolute beginners.

Compiling    [ back to contents]

  1. Nothing's working anymore. Files aren't compiling, and when I try to save source code the files are empty. What do I do? - you might not have any disc space left. Read the Quota page
  2. What are the most common bugs? - 2 common ones this term are
    • cin >>endl; - this can produce pages of error messages. You can only use endl with cout because you output new-line characters.
    • #include <iostream,cmath> - you need a separate #include line for each file you include.
  3. What do the compiler's error messages mean? - sometimes it's not easy to tell - the messages can be confusing, though some compilers are more helpful than others. At least the message will give you a line number telling you where the compiler first got into trouble. The cause of the trouble may be earlier though. Here's an example
    #include <iostream> using namespace std; int main() { if (2==2); cout << "2==2"<< endl; else cout << "2!=2"<< endl; }
    On some of our machines, the compiler will produce this error message. In function `int main()': error: expected primary-expression before "else" error: expected `;' before "else"
    What is a "primary-expression"? It's unhelpful jargon. The line number given is 7, where it expected `;' before "else" (by the way, the emacs editor shows the line number near the bottom of its screen). So should we add a semi-colon just before "else"? On another machine with a newer compiler the error message is In function `int main()': error: syntax error before `else'

    which looks more vague than the other message, but is actually less confusing, because the problem is that there are too many semi-colons in the program, not too few (see the semicolons question for details - the problem is on line 5 of the code).

    So don't expect to the compiler to exactly location and diagnose the problem. The first error in your code may cause lots of further errors, so fix that first.

    Sometimes the cause of the error may be a long time before the reported line-number. If you get an error message saying that there's a problem with your final line of code

    error: syntax error at end of input
    the reason is likely to be that you have an opening brace - a "{" - early in your program that isn't matched by a closing brace - a "}". The compiler won't realise this until it reaches the end of your file.
  4. I get an error message saying "error: reference to 'count' is ambiguous" followed by lots of jargon. What's wrong? - If you've created a variable called count outside of any function it clashes with another variable called count that C++ uses internally. The solution (and it's a good general principle) is to create your count variable inside a function
  5. I get an error message saying that "The left side of '=' must be a modifiable lvalue" or "error: non-lvalue in assignment". What's a modifiable lvalue? - A value that can be modified and can be on the left of an assignment statement. A statement like "7 = i" (or "i = 7" if "i" is a const) would provoke such a message. Perhaps you have something like "if (7=i)" where you meant to have "if (7==i)".
  6. I get a warning message saying "suggest parentheses around assignment used as truth value". Is that anything to worry about? - Probably. If your code has a line like
       if (i=1)
    you are setting i to 1, not comparing i to 1. This isn't illegal (it's equivalent to "if(true)") but you probably meant to use 2 equals signs.
  7. I get a warning message saying " warning: control reaches end of non-void function". Is that anything to worry about? - Probably. Here's a complete program that might provoke that warning.
    int giveMe();
    int main() {
      int answer=giveMe();
    int giveMe() {
      int i=0;
    The trouble is that the giveMe function is supposed to return an integer (i.e. give an integer as its result) but at the moment it returns nothing. Consequently the answer variable in the main function won't be set to anything sensible. The warning message will disappear if the giveMe function is changed to
    int giveMe() {
      int i=0;
      return i;
  8. What does "error: name lookup of `i' changed for new ISO `for' scoping" mean? - First, let's explain some terms. The scope of a variable is the region of code where the variable can be used. ISO is the "International Organization for Standardization", the body who standardised C++ in 1995. They slightly changed C++'s scoping rules.
    Consider the following code fragment
    for (int i=0;i<5;i++) cout << "looping"; i=0;
    The "for" statement creates an integer i that is used to control how many times the loop goes round. Because it's created inside the "for" statement, its scope in ISO C++ extends only to the end of the body of the loop, so by the time i=0; is reached, i no longer exists. With older C++ the i=0; line would have been legal because i's scope was wider.
  9. I get a warning message saying something about 'using namespace std;' - just change your code the way the message suggests. If you want to know more about this, see the start of the C++ Namespaces document.

Executing    [ back to contents]

  1. My code compiles ok but it's not doing the right things - lines are being ignored etc - Some mistakes still produce legal code. For example,
    • cout < "Print this!"; prints nothing - the "<" should be "<<"
    • if (i=0) cout << "Print this!"; prints nothing - the "=" should be "=="
    • vals[i=5]; is legal, but should probably be vals[i]=5;
    • i^2 doesn't give the square of i - use i*i
    • if(1<i<100) doesn't do what mathematicians might expect - use if(1<i and i<100)
    • cin >>i,j,k; doesn't input values into 3 variables - use cin >>i >> j >> k;
    • #include <string> #include <iostream> using namespace std; int main () { std::string s="xy"+'z'; std::cout << s << std::endl; }
      compiles cleanly but doesn't produce an "xyz" string.
  2. My code compiles ok but when I run it nothing happens. What do I do? - Does your program run at all? Put
       cout << "Hello!" << endl;
    at the start of your main routine, and
       cout << "Goodbye!" << endl;
    at the end. If only the "Hello" appears, put
       cout << "Got here!" << endl;

    half way down your program, and continue this way until you've worked out roughly where the problem is.

    You may have an "infinite loop" problem. Have a look at this code fragment.

       int i=0;
       while (i<5)

    Here i starts with the value 0 and is incremented each time the loop's executed until i is 5, after which the rest of the code is run. But suppose the user writes

       int i=0;
       while (i<5);
    Notice the extra semi-colon? It makes a lot of difference. In this situation ";" is a C++ command which does nothing, and it's this command (rather than i++;) which is executed in the loop. Consequently i will always be 0 and the loop never ends!
  3. What are 'nan' and 'inf'? - Sometimes when you print out the result of a calculation you will see inf or nan. inf is short for 'infinity' - you might get it if you do 1/0, for example. If you do 0/0 you might get nan - Not-a-Number. The solution is to check if a value is 0 before dividing by it.

Language features    [ back to contents]

  1. I'm confused about commas and semi-colons - Sometimes you can use a comma instead of a semi-colon, but they do different things - roughly speaking, commas separate and semi-colons terminate.
    • Commas - you need them if you're creating several variables on the same line. For example, "int i,j;" creates 2 integers. Note that the semi-colon ends the statement. Equivalent would be "int i; int j;". You also need them to separate arguments when writing or calling functions. E.g. "pow(2.0,3.0);" calculates 2 cubed. Though commas can be used in other situations, beginners should stick to these uses.
      That said, commas can be leglly used elsewhere. If you try to compile the following code
      #include <iostream> using namespace std; int main() { if (2+2==4) cout << "2+2 is 4" << endl; cout << "So is 3+1" << endl; else cout << "2+2 isn't 4" << endl; }
      it won't work because there are 2 statements between "if" condition and the "else" line, and the "if" condition only expects one. You should bundle the 2 statements together by putting them inside curly brackets ({ and }), but it's also legal to put a comma between the statements to make them into a single statement - i.e.
      ... if (2+2==4) cout << "2+2 is 4" << endl, cout << "So is 3+1" << endl; ...
      Try not to do this - it leads to confusion. Use curly brackets instead.
    • Semi-colons - Semi-colons are used when setting up a "for" loop - the syntax is "for(...;...;...)", though their main use is to end statements. Note that an "if", "while" or "for" statement doesn't end straight after the test condition. It's not illegal to put a semi-colon there, but it's rarely what you want. The following code is legal and will print out "2+2 is 3"
      ... if (2+2==3); cout << "2+2 is 3" << endl; ...
      Why? A semi-colon is also a null command (a command that does nothing), so the "if" test controls whether or not the semi-colon null command is run. The cout command isn't under the control of the "if" test and so is always run. The following layout of the same code gives a better impression of what the code actually does
      ... if (2+2==3) ; cout << "2+2 is 3" << endl; ...
  2. What is an array? - When you have lots of variables that are related in some way, it's useful to clump them together somehow. Arrays offer a way to do this as long as the variables are all of the same type. For example, if you want to store some integer information about each month in an array, you could use
       int month[12];
    to reserve space for 12 integers. The integers would have the names month[0], month[1] ... month[11] because array indexing starts at 0. If you don't want to start at 0 you could ignore the first value and just use month[1], month[2] ... month[12], but you then need 13 integers so you must create the array using
       int month[13];
    The items in the array are usually referred to as elements. They're stored contiguously in memory, so if integers occupy 4 bytes, and the first element starts at memory location 1000 (base 16), the layout of this 13-element array will be
    and the array will occupy 13*4 = 52 bytes.
  3. What is a structure? - Sometimes you want to clump variables together even though they're not all the same type. For example, to clump together information about a football team you might need to use integers, real numbers and text. A structure lets you bundle together all types of variables. Whereas in an array each component is numbered, in a structure each field has a name. The following code defines a structure
       struct Team {
          int points;
          float goal_average;
          string sponsor;
    Note that this code doesn't in itself create a new variable but a new type of variable. As well as being able to create standard, simple variables of type int, float, etc, we've extended the language so that we can now create a Team as well by doing
       Team cambridge;

    The fields of this variable can be individually accessed using cambridge.points, cambridge.goal_average, and cambridge.sponsor. Note that you can have arrays inside structures, and you can have structures of arrays - Team teams[22]; would create an array of 22 Teams. Note also that classes can do everything that structures can do, and more.

    The memory taken up by a structure may be more than the sum of the sizes of the fields - for speed-efficiency reasons, there are sometimes gaps between fields.

  4. What is casting? - Casting is a way to create a new "thing" from an old one. The new "thing" is likely to have the same value as the old one, but it will be a different type of thing. It's somewhat analogous to casting something in bronze - the new object is a copy of the original but is a different type of thing.
    Why is casting sometimes necessary? In C++ if you divide one integer by another, you'll get an integer, so 1/2 will have the result 0. There are good reasons why this is so, but it's not always the result you want. How can you get the answer 0.5? As long as at least one of the values is a floating point number, the result will be a floating point number, so in this case you could do 1.0/2. More often the situation's not so easy. In this code
    int i=1, j=2; float answer; answer=i/j;
    answer will be 0. If i and j were floats we'd get the answer 0.5, but sometimes we're not in a position to make such a change. There are at least 4 ways to rewrite the answer=i/j; line to get the answer 0.5.
    • float tmp=i; answer=tmp/j; - this creates a new floating point variable tmp which has the same value as i. When this is divided by the integer j the result will be a floating point number. However, creating an extra variable like this is messy.
    • answer=(1.0*i)/j; - the 1.0*i expression creates a floating point value, which divided by the integer j will produce a floating point number.
    • answer=(float)i/j; - this is another way to produce a floating point equivalent of i. It's an old method of casting that's unsafe in some other situations.
    • answer=static_cast<float>(i)/j; - this is a newer, safer way of casting. Note that the position of the brackets matters. answer=static_cast<float>(i/j); would give the answer 0 because by the time the casting is done, the integer division has already happened.
  5. How can I add one to a variable i? - Common ways are - i++; (or ++i;) and i=i+1;. If you mix these up and try i=i++; you're asking for trouble - the right-hand side is trying to change i and so is the assignment. As likely as not i won't change.
  6. How can I write my own functions? -
    • Write the function - in particular you need to say what inputs (i.e. what type of "arguments" or "parameters") the function has to be given, and what output is returned. In the following example the function takes 2 floats and returns a float. The returned value can be used by the code that calls the function.
      float rectangle_perimeter(float width, float height) {
         return 2*width + 2*height;
    • Declare the function - before the compiler will let you call a function it has to know the type and number of arguments it takes, so that the compiler can tell you whether you're calling the function correctly. You need to declare the function by providing a function prototype (otherwise known as a "signature"). A prototype for the above function would be
      float rectangle_perimeter(float width, float height);
      (i.e. the same as the first line of the function but with an added semi-colon) This doesn't call the code, it just tells the compiler about the function. The names of the variables here don't matter. It's just as legal to say
      float rectangle_perimeter(float, float);
    • Call the function - when you call the function (i.e. execute it, make it run) you need to provide the right number and type of arguments. Arguments can be numbers or variables. Here, rectangle_perimeter is called twice, giving the same answer each time.
      float answer;
      answer= rectangle_perimeter(5,7);
      float width=5, float height=7;
      answer= rectangle_perimeter(width, height);
      Note that you don't mention the type of the arguments when you call a function - answer=rectangle_perimeter(float width, float height); is wrong. Note also that though the argument names here (width and height) match the names of the arguments in the function code, that's coincidental and irrelevant.
    Here's a complete program showing these features in action. You can hover the point over the text to get descriptions of its purpose.

    float third(int number);

    int main() {
         int i=third(3);

    float third(int num) {
         return num/3.0;
  7. What's the difference between a function prototype and calling a function? - Let's use the sqrt function to discuss this. If you want to find the square root of 5 and put the answer in a variable called i that already exists, you do
    This calls the function. The function runs and it gives an answer. It doesn't mention float or any other type of variable.
    Here's the prototype of the sqrt function.
    float sqrt ( float x );
    This describes the function, so that the compiler knows the number and type of inputs it should have. It doesn't call the function. It doesn't even check to see if the code for that function exists.
  8. What's the difference between "call by reference" and "call by value"? - Suppose we want to write a function that will triple the value of a given variable. We could try the following
    #include <iostream> using namespace std; void triple(int i); int main() { int i=3; cout << "In main, i is " << i << endl; triple(i); cout << "In main, i is now " << i << endl; } void triple(int i) { i=i*3; cout << "in triple, i becomes " << i << endl; }
    But it doesn't work as we wanted - the i in main doesn't change. The problem is that main's i is a different variable to the i in triple. That the 2 variables have the same name is a coincidence (if the i variable in the triple function was called j the code would work just as well). The only link between the 2 variables is that when triple is called, triple's i gets its initial value from main's i - i is being passed "by value".

    If we want to change main's i we need to "call by reference" - note the added ampersands.

    #include <iostream> using namespace std; void triple(int& i); int main() { int i=3; cout << "In main, i is " << i << endl; triple(i); cout << "In main, i is now " << i << endl; } void triple(int& i) { i=i*3; // here i is an alias for main's i }
    If you run this, you'll find that the i variable in main changes. Note that you don't use an ampersand when you call the triple function.
  9. In C++, what's the difference between "if" and "while"? - Quite a lot. The following 2 fragments of code differ only in that one uses "if" and the other uses "while", but the behaviour is very different. Before reading the explanation that follows the code, try to guess what each fragment does.

    // Using if
    int i=0;
    if (i<5) {
      cout << "hello" << endl;
    // Using while
    int i=0;
    while (i<5) {
      cout << "hello" << endl;

    "while" is the start of a loop - while the expression in the brackets is true, the execution of the code cycles round, checking the expression repeatedly. With "if" there's no loop - the code in the braces is run once if the expression is true, otherwise that code isn't run at all. So the first fragment causes "hello" to be printed once, and the second expression causes "hello" to be printed 5 times.

  10. I want to create an array with a size the user types in. Can I do int i; cin >> i ; int array[i];? - Not in C++, but some compilers (e.g. g++, which we use) let you get away with it by default. Standard C++ does have ways to do this - e.g. by using <vector>
  11. How do I convert from a number to a string? - here's an example based on the C++ FAQ
    #include <iostream> #include <sstream> #include <string> std::string convertToString(double x) { std::ostringstream o; if (o << x) return o.str(); // some sort of error handling goes here... return "conversion error"; } int main() { double f=7.77; std::string s=convertToString(f); std::cout << "Length of " << f << " when converted to a string is " << s.size() << std::endl; }
  12. What does return 0; do at the end of the main function? - Not much. Let's first review what return does in other functions. In a function, return ends the running of the function's code and gives a value back to the calling expression. For example, if you wrote a function called squareroot that had return root; at the end of it, then f=squareroot(4); would call squareroot, and the value of root in the squareroot code would be put into the variable f.
    If a program has return 0; at the end of its main routine, the 0 is returned to whatever called the program. Mostly of the time this value is ignored, so you needn't worry about the value returned, but if you want to see the mechanism in action, open a Terminal window. We're going to use a program (written in C) called ls. It lists files and also returns a value from its main function that we can see. Type ls to see what files are in the current folder. Suppose file1 exists, but file2 doesn't. Then
      ls file1
      echo $?
    will display 0 (because the ls command does return 0; when it succeeds, and the command line has a variable called $? which stores the returned value). If you type
      ls file2
      echo $?

    it will display 2 (because the ls command does return 2; when there's "serious trouble"). This return value is often ignored by users, but it's a good habit to return something from main.

    Note that

    • When a function is supposed to return an int, the compiler will usually complain if you don't explicitly do so, but main is a special case - the return isn't compulsory
    • If you have exit(2); anywhere in your code (not just in main) the program will end, and 2 will be returned to whatever called the program.
  13. What are header files? What are they for? What does using namespace std; mean? - Header files are files whose names usually end with .h and contain prototypes, definitions, etc so that you can use some extra routines. By default, C++ doesn't even let you use cout to print to the screen (cout is an "extra" routine), so most programs need to include header files. There are a few dozen standard header files, and you can write your own. Putting #include<iostream> in your program tells the compiler to read in the standard header file(s) for I/O (input/output). But that still isn't enough to let you use cout. You also need to tell the compiler that the cout routine belongs to the standard part of the library of routines. If you put "using namespace std" at the top of your file, the compiler will look in the std (standard) section for routines.This is true for all the standard files (cmath, etc). If you're not including any files, or if you're only using non-standard files (ones you've written yourself for example) then you don't need "using namespace std;".
    An alternative to having "using namespace std;" is to use std::cout instead of cout, std::endl instead of endl, etc., but that's a bit tedious.
  14. How do I convert from a string to a number? - here's an example based on the C++ FAQ
    #include <iostream> #include <sstream> #include <string> double convertFromString(const std::string& s) { std::istringstream i(s); double x; if (i >> x) return x; // some sort of error handling goes here... return 0.0; } int main() { double d; std::string s="3.14"; std::cout << "s= " << convertFromString(s) << " when converted to a double" << std::endl; }
  15. How do I convert a character to a string? - It depends what type of string you mean. Suppose you want to convert char c='A';
    • C-style string (character array) - The following won't work, though it's legal - char *str=(char*)c;. This creates a pointer str that will point to memory location 65 (the ASCII value of 'A'). If you try to read or write at that location, your program will crash. Try this instead - char str[2]; str[0]=c; str[1]=0;. This creates space to store the string and ensures that it's appropriately terminated.
    • C++ string - Use string str; str=c;

CUED-specific issues    [ back to contents]

  1. Can I work away from the DPO? - You can work on your own machine or use your machine to log into the department's computers. Neither option is trouble-free yet
    • Working on your own machine - If you follow the instructions on our Installing C++ compilers page you'll have enough to do the Mich term work and the Mars Lander Exercise.
      What's lacking with both of these options is a start command to set things up ready for the exercises. Also none of the Trading code is available for the Lent term exercise.
    • Working remotely - Our Remote 1AC++ Computing page shows you how to do Michaelmas term's course remotely. More generally, our Remote Access page shows various ways that you can use CUED machines remotely.
  2. [1AC++] Can I work from the command line? - If you open a terminal window and use the cd command to move into the folder where your files are, you can compile from the command line by doing
       compile1AC++ filename[s]

General    [ back to contents]

  1. Why is C++ so hard? - because you haven't read the 1A C++ handout enough times.
  2. Why is the 1A C++ handout so long? - because C++ isn't easy.

1B IDP    [ back to contents]

  1. My code compiles on the workstations but not on ARM - sqrt doesn't work - The maths libraries on the 2 systems aren't (in 2010 at least) quite the same. In the maths library there's a version of sqrt for floats and a version for doubles. If you provide integer parameters the maths library on the workstations copes, but on the ARM system the compiler doesn't know whether to promote the ints to floats or doubles. If you cast both ints to float your code will work on both systems.
  2. I'm having trouble with const and extern - If you have
       int speed=3;
    in a file outside of all functions, then this variable can be accessed from other files as long as the other files have
       extern int speed;
    but if instead of int speed=3; in the first file you have
       const int speed=3;
    the variable isn't visible from other files. Here's a table showing some examples of how the contents of 2 files can interact.
    File 1File 2Outcome
    int i;
    int main()
    extern int i;
    Compiles. There's only one variable called 'i'.
    int i;
    int main()
    int i;
    Fails (multiple definition of 'i') because when the 2 compiled files are linked together they each have an 'i' that is visible to the other.
    extern int i;
    int main()
    int j;
    Fails (undefined reference to 'i') because File 1 expects an 'i' variable to be available from another file.
    extern int i;
    int i;
    int main()
    int j;
    Compiles. The int i; line takes precedence over the extern int i; line.
    static int i;
    int main()
    int i;
    Compiles. File 1's 'i' is private - there are 2 variables called 'i' but they don't clash
    const int i=5;
    int main()
    int i;
    Compiles. File 1's 'i' is private (const vars are static by default) .
    extern const int i=5;
    int main()
    int i;
    Fails (multiple definition of 'i') because when the 2 compiled files are linked together they each have an 'i' that is visible to the other. Why? Because if a variable is declared as extern and it's initialised, then memory for that variable will be allocated. So in this situation there's an 'i' in each file.
    extern const int i=5;
    int main()
    extern const int i;
    Compiles. There's only one 'i' variable in the resulting program - the 'i' in file 2 refers to the 'i' in file 1. If the line in file 2 was extern const int i=2;, linking would fail
  3. When I try to 'Make' my code it's producing strange error messages - This may be because you have a space in a folder-name or file-name associated with the project files. Get rid of the spaces and try again.
  4. When I use the geany IDP icon it doesn't work. - you need to use Make in the Build menu: clicking on the Brick icon isn't enough.
  5. I've created a file in geany, but I can't compile it - Quit from geany, then drop the source file into geany
  6. Do I have to keep selecting and dropping my files into the geany icon? - No. If you do it once and don't create any new files (or add any #include lines) then you can repeatedly Save and Make. If you quit geany and run it again, it should resume from its previous state.

Advanced    [ back to contents]

  1. How can I see if a key's been pressed without having to wait for the user to press the Enter key? I want something like Windows' kbhit - The following works on the Linux Teaching System in a text window, but note that if you interrupt the program while it's in non-blocking mode, normal behaviour won't be restored.
    #include <iostream> #include <cstdlib> #include <unistd.h> #include <time.h> #include <termios.h> #include <sys/select.h> /* According to POSIX 1003.1-2001 */ using namespace std; int tty_mode = 0; struct termios orig_tty; struct termios new_tty; // Sets up terminal for one-char-at-a-time reads void cbreak (void) { if (tty_mode == 0) { tcgetattr(0, &orig_tty); tty_mode = 1; new_tty = orig_tty; } new_tty.c_lflag &= ~(ICANON | ECHO); new_tty.c_cc[VMIN] = 1; new_tty.c_cc[VTIME] = 0; tcsetattr(0, TCSANOW, &new_tty); } // Returns terminal to normal state after cbreak () void normal (void) { if (tty_mode == 1) { tcsetattr(0, TCSANOW, &orig_tty); new_tty = orig_tty; } } // Checks keyboard buffer (stdin) and returns key // pressed, or -1 for no key pressed int keypress (void) { static char keypressed; struct timeval waittime; int num_chars_read; fd_set mask; FD_SET(0, &mask); waittime.tv_sec = 0; waittime.tv_usec = 0; if (select (1, &mask, 0, 0, &waittime)) { num_chars_read = read (0, &keypressed, 1); if (num_chars_read == 1) return ((int)keypressed); } return (-1); } int main() { char c; normal(); cout << "type a character (normal mode): "; cin >> c; cbreak(); cout << "type a character (non-blocking): "; while ( keypress() == -1) { cout << "ok, I'll wait a second" << endl; sleep(1); } cout << "Thanks. Returning to normal behaviour" << endl; normal(); return 0; }
  2. How do I initialize static class members? - Here's an example
    #include <iostream> using namespace std; class fish { public: static int count; fish(void) { cout << "making a fish object" <<endl; count++; cout << "count = " << count << endl; } }; int fish::count=0; int main() { fish fish1, fish2; return(0); }
    Note that the "int fish::count=0;" line can't be inside the main (or any other) function.