PrevNext

C++ 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.

Command 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

Installing g++

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

  1. 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 running clang --version in Terminal).

  2. Install Homebrew.

  3. Install gcc with Homebrew.

    brew install gcc

    According to this if brew doesn't seem to finish for a long time then

    brew install gcc --force-bottle

    probably suffices.

  4. You should be able to compile with g++-#, where # is the version number (e.g., 10). Running the following command

    g++-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.
  5. 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 use bash, and ~/.zshrc if you use zsh).

    alias g++=g++-10

    Once you do so, g++ --version should now output the same thing as g++-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

Simpler: Mingw-w64 (Minimalist GNU for Windows)

Resources
Microsoft

Setting Up MinGW with VS Code

Jetbrains

Setting up MinGW with CLion

Harder: Windows Subsystem for Linux (WSL)

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 tells g++ 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!

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.

What is & fg for?

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)

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 10710^7 integers require 4107103400004\cdot 10^7\cdot 10^{-3}\approx 40000 kilobytes of memory, which is close to 4021640216 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

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 16716^7 bytes 256\approx 256 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!

PrevNext