Table of Contents
Command Line BasicsLinuxMacWindowsInstalling g++On LinuxOn MacOn WindowsSimpler: Mingw-w64 (Minimalist GNU for Windows)Harder: Windows Subsystem for Linux (WSL)C++ with the Command LineBasics of Compiling & RunningRedirecting Input & OutputCompiler Options (aka Flags)Adding Shortcuts (Mac)What is & fg for?Measuring Time & Memory Usage (Mac)Adjusting Stack Size (Mac)Method 1Method 2C++ With the Command Line
Author: Many
Contributors: Vihaan Anand, Benjamin Qi, Hankai Zhang, Anthony Wang, Nathan Wang, Nathan Chen, Michael Lan, Arpan Banerjee
OS-specific instructions for installing and running C++ via the command line.
Prerequisites
Table of Contents
Command Line BasicsLinuxMacWindowsInstalling g++On LinuxOn MacOn WindowsSimpler: Mingw-w64 (Minimalist GNU for Windows)Harder: Windows Subsystem for Linux (WSL)C++ with the Command LineBasics of Compiling & RunningRedirecting Input & OutputCompiler Options (aka Flags)Adding Shortcuts (Mac)What is & fg for?Measuring Time & Memory Usage (Mac)Adjusting Stack Size (Mac)Method 1Method 2Command Line Basics
Resources | ||||
---|---|---|---|---|
CPH | what compiling a simple program looks like |
Linux
Resources | ||||
---|---|---|---|---|
William Shotts | ||||
Ubuntu.com | Works for Linux, Mac, and all Unix terminals |
Mac
Should be mostly the same as Linux ...
Open the Terminal application and familiarize yourself with some basic
commands. Upgrade to zsh
if you
haven't already.
Resources | ||||
---|---|---|---|---|
Jim Hoskins | ||||
Rahul Saigal | keyboard shortcuts / terminal commands | |||
Armin Briegel |
Windows
Resources | ||||
---|---|---|---|---|
Princeton | Java | |||
ComputerHope |
g++
Installing USACO (and most contests)
use GCC's g++
to
compile and run your code. You'll need g++
specifically to use the
#include <bits/stdc++.h>
header file; see
Running Code Locally for
details.
On Linux
GCC is usually preinstalled on most Linux distros. You can check if it is installed with
whereis g++
If it is not preinstalled, you can probably install it using your distro's package manager.
On Mac
Install XCode command line tools.
xcode-select --install
If you previously installed these you may need to update them:
softwareupdate --list # list updates softwareupdate -i -a # installs all updates
After this step,
clang
should be installed (try runningclang --version
in Terminal).Install Homebrew.
Install
gcc
with Homebrew.brew install gcc
According to this if
brew
doesn't seem to finish for a long time thenbrew install gcc --force-bottle
probably suffices.
You should be able to compile with
g++-#
, where # is the version number (e.g., 10). Running the following commandg++-10 --version
should display something like this:
g++-10 (Homebrew GCC 10.2.0_2) 10.2.0 Copyright (C) 2020 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
If you want to be able to compile with just
g++
, write a shell alias! Put the following lines into your shell's rc file (~/.bashrc
if you usebash
, and~/.zshrc
if you usezsh
).alias g++=g++-10
Once you do so,
g++ --version
should now output the same thing asg++-10 --version
.Note: avoid overriding the system
g++
with symlinking or hard-linking as that will almost surely cause problems. Don't worry if you don't know what those terms mean.
On Windows
Mingw-w64 (Minimalist GNU for Windows)
Simpler:Resources | ||||
---|---|---|---|---|
Microsoft | Setting Up MinGW with VS Code | |||
Jetbrains | Setting up MinGW with CLion |
Windows Subsystem for Linux (WSL)
Harder:If you're already accustomed to the Linux Command line, this might be the best option for you.
Windows Subsystem for Linux, commonly referred to as WSL, runs the linux kernel (or an emulation layer, depending on which version you use) within your windows installation. This allows you to use Linux binaries without needing to use Linux as your main Operating System.
Many people use WSL (such as Anthony), but it can be difficult to properly set up.
Resources | ||||
---|---|---|---|---|
Microsoft | difficult for beginners |
If you want to code in (neo)vim, you can install WSL and code through WSL bash.
To install the necessary tools after setting up WSL, you can run the following commands.
On Debian based distributions like Ubuntu:
sudo apt-get install build-essential
On Arch based distributions like Arch Linux:
sudo pacman -Sy base-devel
You can find many tutorials on how to style up WSL and make it feel more cozy. The first step is to use a proper terminal and not the default one that Windows provides. An easy to use option is Windows Terminal, which can be found on the Microsoft Store.
Resources | ||||
---|---|---|---|---|
Setting up your terminal | ||||
Get a beautiful command line interface |
C++ with the Command Line
Basics of Compiling & Running
Consider a simple program such as the following, which we'll save in name.cpp
.
#include <iostream>using namespace std;int main() {int x;cin >> x;cout << "FOUND " << x << "\n";}
It's not hard to
compile & run a C++ program.
First, open up Powershell on Windows, Terminal on Mac, or your distro's terminal
in Linux. We can compile name.cpp
into an executable named name
with the
following command:
g++ name.cpp -o name
Then we can execute the program:
./name
If you type some integer and then press enter, then the program should produce output. We can write both of these commands in a single line:
g++ name.cpp -o name && ./name
Note that &&
ensures that ./name
only runs if g++ name.cpp -o name
finishes successfully.
Redirecting Input & Output
If you want to read standard input from inp.txt
, use the following:
./name < inp.txt
If you want to write standard output to out.txt
, then use the following:
./name > out.txt
They can also be used in conjunction, as shown below:
./name < inp.txt > out.txt
See Input & Output for how to do file input and output within the program.
Compiler Options (aka Flags)
Use
compiler flags
to change the way GCC compiles your code. Usually, we use something like the
following in place of g++ name.cpp -o name
:
g++ -std=c++17 -O2 name.cpp -o name -Wall
-O2
tellsg++
to compile your code to run more quickly while increasing compilation time (see here).-std=c++17
allows you to use features that were added to C++ in 2017. USACO recently upgraded from C++11 to C++17.-Wall
checks your program for common errors. See Debugging for more information.
You should always compile with these flags.
Adding Shortcuts (Mac)
For Users of Linux & Windows
The process is similar for Linux. If you're on Windows, you can use an IDE to get these shortcuts, or you can install WSL (mentioned above).
Retyping the compiler flags above can get tedious. You should define shortcuts so you don't need to type them every time!
Resources | ||||
---|---|---|---|---|
Jonathan Suh | ||||
SO |
First, create your .zshrc
if it doesn't already exist.
touch ~/.zshrc
Open your .zshrc
with a text editor.
open ~/.zshrc
or some text editor (ex. sublime text with subl
).
subl ~/.zshrc
You can add aliases and functions here, such as the following to compile and run C++ on Mac.
co() { g++ -std=c++17 -O2 -o "${1%.*}" $1 -Wall; } run() { co $1 && ./${1%.*} & fg; }
Now you can easily compile and run name.cpp
from the command line with
co name.cpp && ./name
or run name.cpp
. Note that all occurrences of $1
in
the function are replaced with name.cpp
, while ${1%.*}
removes the file
extension from $1
to produce name
.
& fg
for?
What is
Let prog.cpp
denote the following file:
#include <iostream>#include <vector>using namespace std;int main() {vector<int> v;cout << v[-1];}
According to the resource above, the & fg
is necessary for getting zsh
on
Mac to display crash messages (such as segmentation fault). For example,
consider the running the first prog.cpp
above with run prog.cpp
.
If & fg
is removed from the run command above then the terminal displays no
message at all. Leaving it in produces the following (ignore the first two
lines):
[2] 30594 [2] - running ./${1%.*} zsh: segmentation fault ./${1%.*}
Measuring Time & Memory Usage (Mac)
Resources | ||||
---|---|---|---|---|
CF | for Linux | |||
SO | use gtime |
For example, suppose that prog.cpp
consists of the following:
#include <bits/stdc++.h>using namespace std;const int BIG = 1e7;int a[BIG];int main() {int sum = 0;for (int i = 0; i < BIG; ++i) sum += a[i];cout << sum;}
Then co prog.cpp && gtime -v ./prog
gives the following:
Command being timed: "./prog" User time (seconds): 0.01 System time (seconds): 0.01 Percent of CPU this job got: 11% Elapsed (wall clock) time (h:mm:ss or m:ss): 0:00.22 Average shared text size (kbytes): 0 Average unshared data size (kbytes): 0 Average stack size (kbytes): 0 Average total size (kbytes): 0 Maximum resident set size (kbytes): 40216 Average resident set size (kbytes): 0 Major (requiring I/O) page faults: 91 Minor (reclaiming a frame) page faults: 10088 Voluntary context switches: 3 Involuntary context switches: 38 Swaps: 0 File system inputs: 0 File system outputs: 0 Socket messages sent: 0 Socket messages received: 0 Signals delivered: 0 Page size (bytes): 4096 Exit status: 0
Note that integers require kilobytes of memory, which is close to in the above output as expected.
Adjusting Stack Size (Mac)
Warning!
This section might be out of date.
Let A.cpp
denote the following program:
#include <iostream>using namespace std;int res(int x) {if (x == 200000) return x;return res(x + 1);}int main() { cout << res(0) << "\n"; }
If we compile and run this with g++ A.cpp -o A && ./A
, this outputs 200000
.
However, changing 200000
to 300000
gives a segmentation fault. Similarly,
#include <iostream>using namespace std;int main() {int arr[2000000];cout << arr[0] << "\n";}
runs, but changing 2000000
to 3000000
also gives a segmentation fault. This
is because the stack size on Mac appears to be limited to 8 megabytes by
default.
Resources | ||||
---|---|---|---|---|
Wikipedia | explanation of the issue |
Note that USACO does not have a stack size limit, aside from the usual 256 MB memory limit. Therefore, code that crashes locally due to a stack overflow error may still pass on the USACO servers. To get your code running locally, use one of the methods below.
Warning!
This matters particularly for contests such as Facebook Hacker Cup where you submit the output of a program you run locally.
Method 1
Resources | ||||
---|---|---|---|---|
SO |
ulimit -s 65532
will increase the stack size to about 64 MB. Unfortunately,
this doesn't work for higher numbers.
Method 2
Resources | ||||
---|---|---|---|---|
CF | people complain about FHC every year |
To get around this, we can pass a
linker option. According
to the manual for
ld
(enter
man ld
in Terminal), the option -stack_size size
does the following:
Specifies the maximum stack size for the main thread in a program. Without this option a program has a 8MB stack. The argument size is a hexadecimal number with an optional leading 0x. The size should be a multiple of the architecture's page size (4KB or 16KB).
So including -Wl,-stack_size,0x10000000
as part of your compilation command
will set the maximum stack size to bytes megabytes, which
is usually sufficient. However, running the first program above with 200000
replaced by 1e7
still gives an error. In this case, you can further increase
the maximum stack size (ex. changing 0x10000000
to 0xF0000000
).
On windows, adding -Wl,--stack,268435456
as a part of your compilation flags
should do the trick. The 268435456
corresponds to 268435456
bytes, or 256
megabytes. If you are using Windows PowerShell, make sure to wrap it in
quotations (like so: "-Wl,--stack,268435456"
), since commas are considered to
be special characters.
Module Progress:
Join the USACO Forum!
Stuck on a problem, or don't understand a module? Join the USACO Forum and get help from other competitive programmers!