C++ Tips and Tricks (Bruce Merry)
C++ Tips and Tricks (Bruce Merry)
tricks
Bruce Merry
Portable tips
Assertions
String Conversions
References
Typedefs
C++ tips and tricks
I/O performance
GCC tips
Compilation flags
Header files Bruce Merry
Traps
Undefined Behaviour
Surprising Behaviour
Traps
2 GCC tips
Undefined Behaviour
Surprising Behaviour
Compilation flags
Header files
3 Traps
Undefined Behaviour
Surprising Behaviour
Outline
Traps
2 GCC tips
Undefined Behaviour
Surprising Behaviour
Compilation flags
Header files
3 Traps
Undefined Behaviour
Surprising Behaviour
Assertions
Portable tips
Assertions
String Conversions
References
Typedefs
I/O performance
To disable assertions, add
GCC tips
Compilation flags
#define NDEBUG
Header files
int main() {
assert(foo());
}
Caution
int main() {
assert(foo());
}
When assertions are disabled, the expression is not
evaluated.
Outline
Traps
2 GCC tips
Undefined Behaviour
Surprising Behaviour
Compilation flags
Header files
3 Traps
Undefined Behaviour
Surprising Behaviour
String-To-Integer Conversions
Portable tips
Assertions
String Conversions Use istringstream to treat a string as an input stream:
References
Typedefs
I/O performance #include <sstream>
GCC tips int x;
Compilation flags
Header files istringstream stream("123");
Traps
Undefined Behaviour
stream >> x;
Surprising Behaviour // Now x == 123
String-To-Integer Conversions
Portable tips
Assertions
String Conversions You can reduce typing by using a C function instead:
References
Typedefs
I/O performance #include <cstdlib>
GCC tips string xstr = "123";
Compilation flags
Header files string ystr = "12345678912345678";
Traps
Undefined Behaviour
int x = atoi(xstr.c_str());
Surprising Behaviour long long y = atoll(ystr.c_str());
String-To-Integer Conversions
Portable tips
Assertions
String Conversions C++11 has a more convenient wrapper:
References
Typedefs
I/O performance #include <string>
GCC tips string xstr = "123";
Compilation flags
Header files string ystr = "12345678912345678";
Traps
Undefined Behaviour
int x = stoi(xstr);
Surprising Behaviour long long y = stoll(ystr);
Integer-To-String Conversions
Portable tips
Assertions
String Conversions The general solution is ostringstream:
References
Typedefs
I/O performance #include <sstream>
GCC tips ostringstream o;
Compilation flags
Header files o << 123;
Traps
Undefined Behaviour
string s = o.str();
Surprising Behaviour // s == "123"
Integer-To-String Conversions
Portable tips
Assertions
String Conversions
References
Typedefs
I/O performance
C++11 again has a convenience wrapper
GCC tips
Compilation flags
#include <string>
Header files
string s = to_string(123);
Traps
Undefined Behaviour
Surprising Behaviour
Outline
Traps
2 GCC tips
Undefined Behaviour
Surprising Behaviour
Compilation flags
Header files
3 Traps
Undefined Behaviour
Surprising Behaviour
Introduction
Portable tips
Assertions
String Conversions
References
Typedefs In Java and Python, all objects are references:
I/O performance
GCC tips
Passing to a function is cheap: just another reference
Compilation flags
Header files Callee function can modify the object
Traps
Undefined Behaviour
Every object must be explicitly created (e.g., with new)
Surprising Behaviour
C++ Default
Portable tips
Assertions
By default, C++ objects are values:
String Conversions
References
Typedefs
I/O performance
GCC tips
Compilation flags
Header files
Traps
Undefined Behaviour
Surprising Behaviour
C++ Default
Portable tips
Assertions
By default, C++ objects are values:
String Conversions
References
Typedefs
void foo(vector<string> grid)
I/O performance
{
GCC tips
Compilation flags
// foo operates on a *copy* of grid
Header files
}
Traps
Undefined Behaviour
Surprising Behaviour
C++ Default
Portable tips
Assertions
By default, C++ objects are values:
String Conversions
References
Typedefs
void foo(vector<string> grid)
I/O performance
{
GCC tips
Compilation flags
// foo operates on a *copy* of grid
Header files
}
Traps
Undefined Behaviour
Surprising Behaviour
string mystrings[4];
// array contains 4 empty strings
Reference arguments
Traps
Undefined Behaviour
Surprising Behaviour
Reference arguments
Traps
Can also qualify references as const:
Undefined Behaviour
Surprising Behaviour void foo(const vector<string> &grid)
{
// foo is prevented from modifying grid
}
Reference Variables
Portable tips
Assertions
Variables can be references, but they cannot be changed:
String Conversions
References
Typedefs
vector<string> strings(5);
I/O performance
string &first = strings[0];
GCC tips
Compilation flags
string &second = strings[1];
Header files
string &something; // error
Traps
Undefined Behaviour
first += "hello"; // appends to strings[0]
Surprising Behaviour
// copy one *string* to another:
second = first;
Pointers
Portable tips
Assertions
String Conversions
References Pointers are similar to references
Typedefs
I/O performance
Can be changed to point at other things
GCC tips
Compilation flags Can be null pointers
Header files
Traps
2 GCC tips
Undefined Behaviour
Surprising Behaviour
Compilation flags
Header files
3 Traps
Undefined Behaviour
Surprising Behaviour
Typedefs
Portable tips
Assertions
String Conversions Can define shorthand for other types:
References
Typedefs
I/O performance typedef long long ll;
GCC tips typedef vector<vector<ll> > vvll;
Compilation flags
Header files ...
Traps
Undefined Behaviour
// declare a vector<vector<long long> >:
Surprising Behaviour vvll myarray;
Outline
Traps
2 GCC tips
Undefined Behaviour
Surprising Behaviour
Compilation flags
Header files
3 Traps
Undefined Behaviour
Surprising Behaviour
Improving Read Performance
Portable tips
cout << 123 << endl;
Assertions
String Conversions
cout << 123 << ’\n’;
References
Typedefs
I/O performance
GCC tips
Compilation flags
Header files
Traps
Undefined Behaviour
Surprising Behaviour
Improving Write Performance
Portable tips
cout << 123 << endl;
Assertions
String Conversions
cout << 123 << ’\n’;
References
Typedefs
I/O performance
Using endl flushes the output.
GCC tips
Compilation flags
Header files
Traps
Undefined Behaviour
Surprising Behaviour
Improving Write Performance
Portable tips
cout << 123 << endl;
Assertions
String Conversions
cout << 123 << ’\n’;
References
Typedefs
I/O performance
Using endl flushes the output.
GCC tips
Compilation flags
Header files Table : Output performance (time to write 107 integers)
Traps
Undefined Behaviour
Surprising Behaviour Method Time (s)
endl 2.34
’\n’ 0.75
printf 0.80
Outline
Traps
2 GCC tips
Undefined Behaviour
Surprising Behaviour
Compilation flags
Header files
3 Traps
Undefined Behaviour
Surprising Behaviour
Warnings
Portable tips
Assertions
String Conversions
References
Typedefs
I/O performance
GCC tips
-Wall Provide lots of helpful warnings
Compilation flags
Header files
-W Provide even more warnings, some useless
Traps
Undefined Behaviour
Surprising Behaviour
Optimisation
Portable tips
Assertions
String Conversions Use -O2 to optimize your code
References
Typedefs
I/O performance
Speedup varies a lot, depending on code
GCC tips
Compilation flags
Header files
Traps
Undefined Behaviour
Surprising Behaviour
Optimisation
Portable tips
Assertions
String Conversions Use -O2 to optimize your code
References
Typedefs
I/O performance
Speedup varies a lot, depending on code
GCC tips Interferes with debugging tools
Compilation flags
Header files
Traps
Undefined Behaviour
Surprising Behaviour
Optimisation
Portable tips
Assertions
String Conversions Use -O2 to optimize your code
References
Typedefs
I/O performance
Speedup varies a lot, depending on code
GCC tips Interferes with debugging tools
Compilation flags
Header files Undefined behaviour can change
Traps
Undefined Behaviour
Surprising Behaviour
Optimisation
Portable tips
Assertions
String Conversions Use -O2 to optimize your code
References
Typedefs
I/O performance
Speedup varies a lot, depending on code
GCC tips Interferes with debugging tools
Compilation flags
Header files Undefined behaviour can change
Traps
Undefined Behaviour Some warnings only work with optimisation
Surprising Behaviour
Optimisation
Portable tips
Assertions
String Conversions Use -O2 to optimize your code
References
Typedefs
I/O performance
Speedup varies a lot, depending on code
GCC tips Interferes with debugging tools
Compilation flags
Header files Undefined behaviour can change
Traps
Undefined Behaviour Some warnings only work with optimisation
Surprising Behaviour
Traps
2 GCC tips
Undefined Behaviour
Surprising Behaviour
Compilation flags
Header files
3 Traps
Undefined Behaviour
Surprising Behaviour
Including The Standard Libraries
Portable tips
Assertions
String Conversions
References
Typedefs
I/O performance
This will pull in all the standard library headers
GCC tips
Compilation flags
#include <bits/stdc++.h>
Header files
Traps
2 GCC tips
Undefined Behaviour
Surprising Behaviour
Compilation flags
Header files
3 Traps
Undefined Behaviour
Surprising Behaviour
Uninitialized Data
Portable tips
Assertions
String Conversions
References
Typedefs int x;
I/O performance
GCC tips
int y[3];
Compilation flags vector<int> z(4);
Header files
Traps
cout << x << ’ ’ << y[1] << ’ ’ << z[2];
Undefined Behaviour
Surprising Behaviour Which values are well-defined?
Uninitialized Data
Declared in an array
Declared in a struct/class and not set by constructor
Out-of-range Array Access
Portable tips
Assertions
String Conversions
References
Typedefs
I/O performance
int x[3] = {1, 2, 3};
GCC tips
Compilation flags
x[3] = 4;
Header files
Traps
2 GCC tips
Undefined Behaviour
Surprising Behaviour
Compilation flags
Header files
3 Traps
Undefined Behaviour
Surprising Behaviour
Mod on Negative Values
Portable tips
Assertions
String Conversions 5 % 3 == 2
References
Typedefs
I/O performance
-5 % 3 == -2 (unlike Python)
GCC tips
Compilation flags
When a problem asks for an answer modulo M:
Header files
Traps ans %= M;
Undefined Behaviour
Surprising Behaviour
if (ans < 0)
ans += M;
Unsigned Is Evil
Portable tips
Assertions
String Conversions What is wrong with this code?
References
Typedefs
I/O performance // One pass of bubblesort
GCC tips
Compilation flags
for (int i = 0; i < arr.size() - 1; i++)
Header files if (arr[i] > arr[i + 1])
Traps swap(arr[i], arr[i + 1]);
Undefined Behaviour
Surprising Behaviour
Unsigned Is Evil
Portable tips
Assertions
String Conversions What is wrong with this code?
References
Typedefs
I/O performance // One pass of bubblesort
GCC tips
Compilation flags
for (int i = 0; i < arr.size() - 1; i++)
Header files if (arr[i] > arr[i + 1])
Traps swap(arr[i], arr[i + 1]);
Undefined Behaviour
Surprising Behaviour
Portable tips
Assertions
String Conversions
References
Typedefs
I/O performance
Function parameters and local variables kept on a stack
GCC tips Stack size limits possible recursion depth
Compilation flags
Header files
Linux defaults to an 8 MiB stack!
Traps
Undefined Behaviour
Surprising Behaviour
So be careful with more than 100 000 levels of recursion.