Expressions Operators and Operands Operators obey arity associativity
Expressions: Operators and Operands • Operators obey arity, associativity, and precedence int result = 2 * 3 + 5; // assigns 11 • Operators are often overloaded for different types string name = first + last; // concatenation • An lvalue gives a location; an rvalue gives a value – Left hand side of an assignment must be an lvalue – Prefix increment and decrement take and produce lvalues – Posfix versions (and &) take lvalues, produce rvalues • Beware accidentally using the “future equivalence” operator, e. g. , if (i = j) instead of if (i == j) • Avoid type conversions if you can, and only use named casts (if you must explicitly convert types) CSE 332: C++ expressions
Expressions as Program Inputs • E. g. , what if we wanted prefix arithmetic, not infix. /prefix_adder + 8 + 9 10 • Can write a program to parse prefix expressions + 8 + 9 10 + + 8 9 10 • These are equivalent to their infix versions (8 + (9 + 10)) ((8 + 9) + 10) • Key idea: walk through expression, calculate value same result 1 2 8 + 4 9 3 + different order 5 10 CSE 332: C++ expressions 3 8 1 + 2 + 4 9 5 10
Exploring an Example Prefix Addition Program • A debugger helps us observe a program’s behavior – Step through (and into) functions – Watching the call stack and variable values • But, before we start using the fancy tools… – What do we expect the program to do? – How might the program fail? – Can we make predictions and test them? • Thinking: the most powerful way to explore or debug – Scientific method should guide what you do • Hypothesis prediction experiment analysis (and repeat) – Tools can help you follow this disciplined approach faster CSE 332: C++ expressions
How the Prefix Addition Program Can Fail • Too few arguments in expression. /prefix_adder + 8 + 9 • Cannot calculate result + 8 + 9 (needs another value to finish 2 nd + operation) 1 2 8 + 4 9 3 + ? ? ? • Try this on your own in the studio, for practice CSE 332: C++ expressions
Example Program Header File // prefix_adder. h // // author: Chris Gill cdgill@cse. wustl. edu // // purpose: Declarations for a simple prefix adder program, which // takes the command line arguments as a prefix addition // expression and computes an integer result. #ifndef PREFIX_ADDER_H #define PREFIX_ADDER_H // Function prototypes. void usage (char * program_name); int parse_and_compute (int & current_index, int last_index, char *argv[]); #endif /* PREFIX_ADDER_H */ CSE 332: C++ expressions
Example Program Source File / Usage Function // prefix_adder. cc // // author: Chris Gill cdgill@cse. wustl. edu // // purpose: definitions for a simple prefix adder program, which // takes the command line arguments as a prefix addition // expression and computes an integer result. #include "prefix_adder. h" #include <iostream> <string> <sstream> <cstring> // // For For std output stream and manipulators. standard C++ strings. standard string streams. C-style string functions // Helper function to print out the program's usage message. void usage (char * program_name) { cout << "Usage: " << program_name << " <argument> [<argument>]. . . " << endl << "Purpose: computes program arguments as prefix addition expression" << endl; } CSE 332: C++ expressions
Example Program Main Function int main (int argc, char *argv[]) { // A few useful constants for argument positions const int minimum_arguments = 2; const int starting_index = 1; const int program_name_index = 0; if (argc < minimum_arguments || strcmp (argv[starting_index], "--help") == 0) { usage (argv[program_name_index]); return 1; } try { // Pass the current and last index to use, and the array, to the // expression parsing function, and store the result. int current_position = starting_index; int value = parse_and_compute (current_position, argc - 1, argv); // Print out the result, and return success value. cout << "The value calculated is " << value << endl; return 0; } catch (. . . ) { cout << "caught exception" << endl; return -1; } } CSE 332: C++ expressions
Example Program Parsing Function // Helper function to parse the input symbols and compute a value. int parse_and_compute (int & current_index, int last_index, char *argv[]) { // make sure we're still in the argument range if (current_index > last_index) { throw 1; } // look for a single-symbol addition operator if (strlen (argv[current_index]) == 1 && *(argv[current_index]) == '+') { int first_operand = parse_and_compute ( ++current_index, last_index, argv); int second_operand = parse_and_compute (current_index, last_index, argv); return first_operand + second_operand; } // treat anything else as an integer else { int result; istringstream i (argv[ current_index++]); i >> result; return result; } } CSE 332: C++ expressions
More Generally When Debugging Code May Help • When your program crashes – Finding out where it crashed – Examining program memory at that point • When a bug occurs in your program – Watching program variables – Identifying where a problem occurs (and why) • Tracing through a program’s behaviors – Learning what a program does – Good basic testing approach CSE 332: C++ expressions
Another Motivation Debugging “Core” Dumps • A program dumps a memory image when it crashes – creates a file (called “core” on Linux) and then exits – this happens when a program receives certain signals: • Segmentation fault – accessed memory it does not own – or dereferenced a 0 pointer • Bus error – divided by zero – corrupted stack • Debuggers are very useful to examine “core” files – When your program crashes within Visual Studio – On Linux: gdb myprogram core CSE 332: C++ expressions
Debugging on Various Platforms • We’ll use Visual Studio’s graphical debugger – Much more on this as we go through the semester – Set command line arguments in the project properties – It’s also good to know about common text-based tools • gdb – Debugger provided with the g++ compiler (e. g. , on Linux) – Using –g switch embeds debug info during compilation – Runs well within emacs (Esc-X debug) CSE 332: C++ expressions
Some Essential Debugging Commands • start (or restart) execution in the debugger – Visual Studio: F 5 (Start Debugging) – gdb: run (also give its command line arguments) • execute one line, stepping into any functions – Visual Studio: F 11 (Step Into) – gdb: step • execute one line, stepping over any functions – VS: F 10 (Step Over) – gdb: next • set breakpoint at a line or function entry point – VS: F 9 (Toggle Breakpoint) – gdb: break (can give file and line, function, etc. ) CSE 332: C++ expressions
- Slides: 12