Illya Starikov
After using a fairly large, matured language for a reasonable period of time, find peculiarities in the language or the libraries is guaranteed to happen. However, given it’s history, I have to say C++ definitely allows for some of the strangest peculiarities in it’s syntax. Below I list three that are my favorite.
Ternaries Returning lvalues
You might be familiar with ternaries as condition ? do something : do something else
, and they become quite useful in comparison to the standard if-else. However, if you’ve dealt with ternaries a lot, you might have noticed that ternaries also return lvalues/rvalues. Now, as the name suggests suggests, you can assign to lvalues (lvalues are often referred to as locator values). So something like so is possible:
std::string x = "foo", y = "bar";
std::cout << "Before Ternary! ";
// prints x: foo, y: bar
std::cout << "x: " << x << ", y: " << y << "\n";
// Use the lvalue from ternary for assignment
(1 == 1 ? x : y) = "I changed";
(1 != 1 ? x : y) = "I also changed";
std::cout << "After Ternary! ";
// prints x: I changed, y: I also changed
std::cout << "x: " << x << ", y: " << y << "\n";
Although it makes sense, it’s really daunting; I can attest to never seeing it in the wild.
Commutative Bracket Operator
An interesting fact about C++ bracket operator, it’s simply pointer arithmetic. Writing array[42]()
is actually the same as writing *(array + 42)
, and thinking in terms of x86/64 assembly, this makes sense! It’s simply an indexed addressing mode, a base (the beginning location of array) followed by an offset (42). If this doesn’t make sense, that’s okay. We will discuss the implications without any need for assembly programming.
So we can do something like *(array + 42)
, which is interesting; but we can do better. We know addition to be commutative, so wouldn’t saying *(42 + array)
be the same? Indeed it is, and by transitivity, array[42]()
is exactly the same as 42[array]()
. The following is a more concrete example.
std::string array[50];
42[array] = "answer";
// prints 42 is the answer
std::cout << "42 is the " << array[42] << ".";
Zero Width Space Identifiers
This one has the least to say, and could cause the most damage. The C++ standard allows for hidden white space in identifiers (i.e. variable names, method/property names, class names, etc.). So this makes the following possible.
int number = 1;
int number = 2;
int number = 3;
std::cout << number << std::endl; // prints 1
std::cout << number << std::endl; // prints 2
std::cout << number << std::endl; // prints 3
Using \u
as a proxy for hidden whitespace character, the above code can be re-written as such:
int n\uumber = 1;
int nu\umber = 2;
int num\uber = 3;
std::cout << n\uumber << std::endl; // prints 1
std::cout << nu\umber << std::endl; // prints 2
std::cout << num\uber << std::endl; // prints 3
So if you’re feeling like watching the world burn, this would be the way to go.
One of the reasons I kept CodeRunner handy was its ability to quickly compile code. With a single click of a button, I could run any of my frequently used languages. It didn’t matter if it was an interpreted or compiled language, so I could virtually run anything, like:
- C/C
- Python
- Lua
- LaTeX
- Perl
However, in the last few months I started using Vim. Heavily. So much so I was trying to use Vim command in the CodeRunner buffers. So I decided I wanted to have the functionality, and in vim-esque fashion, I mapped to my leader key: <leader>r
. The mnemonic <leader>r
un helped me remember the command on the first few tries.
To get the functionality, just add the following to your .vimrc
.
function! MakeIfAvailable()
if filereadable("./makefile")
make
elseif (&filetype == "cpp")
execute("!clang++ -std=c++14" + bufname("%"))
execute("!./a.out")
elseif (&filetype == "c")
execute("!clang -std=c11" + bufname("%"))
execute("!./a.out")
elseif (&filetype == "tex")
execute("!xelatex" + bufname("%"))
execute("!open" + expand(%:r))
endif
endfunction
augroup spaces
autocmd!
autocmd FileType c nnoremap <leader>r :call MakeIfAvailable()<cr>
autocmd FileType cpp nnoremap <leader>r :call MakeIfAvailable()<cr>
autocmd FileType tex nnoremap <leader>r :call MakeIfAvailable()<cr>
autocmd FileType python nnoremap <leader>r :exec '!python' shellescape(@%, 1)<cr>
autocmd FileType perl nnoremap <leader>r :exec '!perl' shellescape(@%, 1)<cr>
autocmd FileType sh nnoremap <leader>r :exec '!bash' shellescape(@%, 1)<cr>
autocmd FileType swift nnoremap <leader>r :exec '!swift' shellescape(@%, 1)<cr>
nnoremap <leader>R :!<Up><CR>
augroup END
One of the most frustrating things to deal with is the trailing space. Trailing spaces are such a pain because
- They can screw up string literals
- They can break expectations in a text editor (i.e. jumping to a new line or the end of the line)
- They can actually break programming languages
- They are just unflattering
However, in Vim, it takes one autocmd
to alleviate this.
augroup spaces
autocmd!
autocmd BufWritePre \* %s/s+$//e
augroup END
On every buffer save substitute spaces at the end of the line with nothing. Easy!
Mercedes-Benz NTG5 STAR2
Fully integrated high-end multimedia system with 6-disc DVD changer, hard-drive navigation system, internet browser, telephony plus DVD video and Music Register, shown on high-resolution 21.3 cm colour TFT display.

The NTG Star2 is a mid-2010s Mercedes-Benz in‑car navigation/infotainment system (part of the COMAND/Audio20 series). In practice it was the NTG5‑generation system used in models like the W205 C‑Class, W222 S‑Class, GLC, etc. For audio and navigation it typically used the standard 7″ (17.8 cm) TFT display and console controller. Importantly, NTG Star2 used Garmin’s “Map Pilot” technology for GPS navigation in Audio20-equipped cars – inserting a Garmin SD‑card lets the Audio20 unit run 3D maps and routing. (The COMAND head unit itself was Mercedes-made, but Garmin supplied the map/database software.)
NTG Star2 debuted around 2014–2015 as the successor to the NTG4.5 COMAND system. Mercedes introduced it on new models (for example, the 2015–2020 C‑Class W205 and later E‑Class and GLC) as COMAND Online (NTG5) hardware. These NTG5/Star2 units featured a built‑in hard drive for media and optional CD/DVD storage. Around 2018–2019 Mercedes began updating Star2 to a new software version called “Star1” (this was essentially a software revision to enable features like Apple CarPlay). As one forum noted, “my new [head unit] is called NTG Star1 and CarPlay works – the old one was NTG Star2”. (In other words, Star2 was the original NTG5 software on older Audio20 hardware; Star1 was the newer update with smartphone integration.)
Today NTG Star2 systems remain supported through Mercedes accessories and parts. Mercedes still sells Garmin Map Pilot SD navigation cards and software updates for NTG5/Star2 systems. For vehicles that came with NTG Star2, a dealer or owner can purchase official updates (e.g. Europe 2020/2021 map packs) for the Garmin Map Pilot. Mercedes also offered an accessory COMAND Online head unit upgrade with DVD changer – a high-end multimedia unit with a 6‑disc changer and hard‑drive nav that replaces the original unit. In short, the NTG Star2 system remains available on its original models (C‑Class, S‑Class, etc.) and can be serviced or upgraded using genuine Mercedes parts (for example, the COMAND Online unit with DVD changer or Garmin Map Pilot module).
While Mercedes-Benz designed the NTG Star2 hardware and user interface, Garmin’s involvement was confined to the navigation content. On Audio20/NTG5 Star2 cars, Garmin supplied the Map Pilot navigation module (SD card and software) that plugs into the Mercedes system. There is no ongoing Garmin development of NTG Star2 itself – Garmin’s input was the map database and guidance engine. All system updates (DVD/DVD changer upgrades or map updates) are handled through Mercedes-Benz parts (including Garmin-branded map cards sold by Mercedes).
Since reading about its faults in The Not So Short Introduction to LaTeX (highly recommended read), I have avidly stayed away form eqnarray
. However, I feel as if the book didn’t covey the ideas as well as it should; also, it suggestion was IEEEeqnarray
, apposed to the classically recommended align
. This article on TeX User Groups conveys ideas more eloquently and provides better alternatives.
The most frustrating thing about compiling LaTeX in a terminal is the wall of text that gets written to stdout. An easy solution would be piping to dev/null
; except then you wouldn’t be able to get error messages (even if only pipe stdout to dev/null
and keep stderr). So, I made a solution that handles the compiling by piping error messages to less
. The syntax of latexerr FILENAME
will compile the files. Passing --clean
will delete temporary LaTeX files.
#!/bin/bash
# USAGE: ./script FILE --clean --glossary
extensions_to_delete=(\
gz fls fdb_latexmk blg bbl log\
aux out nav toc snm glg glo xdy
)
compile_and_open() {
argument="$1"
auxname="${argument%.tex}.aux"
errors=$(pdflatex -shell-escape -interaction=nonstopmode -file-line-error "$argument" | grep ".*:[0-9]*:.*")
if [[ -n $errors ]]; then
echo "$1 Errors Detected"
echo "$errors" | less
else
open_file $1
echo "$1 Compile Successful"
fi
}
open_file() {
filename=`echo "$1" | cut -d'.' -f1`
open "$filename.pdf"
echo "$filename Opened"
}
# http://tex.stackexchange.com/questions/6845/compile-latex-with-bibtex-and-glossaries
glossary() {
compile $1
makeglossaries $1
compile $1
compile $1
}
clean() {
for file in $(dirname $1)/*; do
filename=$(basename "$file")
extension="${filename##*.}"
filename="${filename%.*}"
for bad_extensions in "${extensions_to_delete[@]}" ; do
if [[ $bad_extensions = $extension ]]; then
rm $file
echo "$file Deleted"
fi
done
done
}
main() {
compile_and_open $1
if [ "$3" = "--glossary" ]; then
glossary $1
fi
if [ "$2" = "--clean" ]; then
clean $1
fi
}
main "$@"
Updated version(s) will be posted here.
Painting Gabriel’s Horn
A horn you can fill with paint, but you can't paint the surface.
There are many things in the world of mathematics that are really quite wonderful — however, I am not sure there will be anything more wonderful yet unintuitive than Gabriel's Horn.
Gabriel's Horn is thus: suppose you have the function $y = \frac{1}{x}$ where $x \in \mathbb{R}^+, 1 \leq x \leq \infty$, rotated around the $x$ axis; not too difficult to conceptualize, it looks like a horn of sorts. But here's the paradox.
Suppose we want to calculate the volume. Simple enough, using solids of revolution, we can show the volume to be:
$$
V = \pi \lim_{t \rightarrow \infty} \int _1 ^t \frac{1}{x^2} dx = \pi \lim _{t \rightarrow \infty} ( 1 - \frac{1}{t} ) = \pi
$$
A simple, elegant solution; we can expect the volume to be exactly $\pi$. So, let's see about the surface area.
We know the general definition of the arc length to be $\int _a ^b \sqrt{1 + f'(x)^2}$, so combining this with our solids of revolution, we should get
$$
A = 2\pi \lim _{t \rightarrow \infty} \int _1 ^t \frac{1}{x} \sqrt{1 + \left( -\frac{1}{x^2} \right)^2 } dx
$$
However, this is not a trivial integral; however, there is a trick we can do. Suppose we take the integral $$2\pi \lim _{t \rightarrow \infty} \int _1 ^t \frac{dx}{x}$$ instead, and we can prove this integral will always be equal to or smaller than the former integral (because of the disappearance of $\sqrt{1 + (-\frac{1}{x^2})}$). So, taking this rather trivial integral, we can see that
$$
A \geq 2\pi \lim _{t \rightarrow \infty} \int _1 ^t \frac{dx}{x} \implies A \geq \lim _{t \rightarrow \infty} 2\pi \ln(t)
$$
Wait a minute; it's divergent! So we know the volume $V = \pi$, but the surface area $A \geq \infty$. This is no mistake, the math is valid. And that is simply wonderful.
A horn you can fill with paint, but you can't paint the surface.
You've seen it in the movies or read about it in the books: the Monty Hall Problem. The premise is such: you are on a game show. There's three doors, behind one is a prize. Behind the other two is nothing besides disappointment. You pick an arbitrary door. The game host, Monty Hall, opens one of the other doors and reveals that there is no prize behind it. Keeping the other two doors closed, he asks you if you would like to switch your choice or remain with your original pick. What should you do? Benc Campbell has a solution.
You're meaning to tell me that if I switch mid-game, an offer by the man who set up all the doors and the respective prizes, I would have a better chance of winning? How is this possible? Seems a bit counterintuitive. Seems almost wrong. Fortunately, we can test this with a simple program.
import Darwin // for arc4random_uniform
func random(from from: Int, to: Int, except: Array<Int>? = nil) -> Int {
let number = Int(arc4random_uniform(UInt32(to - from + 1))) + from // produce bounds, +1 to make inclusive
if except != nil && except?.indexOf(number) != nil {
return random(from: from, to: to, except: except) // recursively call until you find the a number that doesn't contain the value
}
return number
}
// returns if you won when you stayed and switched, respectively
func montyHall(doors: Int) -> (Bool, Bool) {
let originalDoor = random(from: 1, to: doors) // Your original choice
let correctDoor = random(from: 1, to: doors) // The winning choice.
let revealedDoor = random(from: 1, to: doors, except: [correctDoor, originalDoor]) // The door the judge reveals
let switchedDoor = random(from: 1, to: doors, except: [revealedDoor, originalDoor]) // Supposing you switched, you woudl
return (originalDoor == correctDoor, switchedDoor == correctDoor)
}
let testValues = [100, 1_000, 10_000, 100_000, 1_000_000, 1_000_000]
let actualNumberOfDoors = 3
for value in testValues {
var stayingCounter = 0, switchingCounter = 0
for _ in 0...value {
let (stayedWon, switchedWon) = montyHall(actualNumberOfDoors)
if stayedWon { stayingCounter += 1 }
if switchedWon { switchingCounter += 1 }
}
print("Test Case: \(value). Staying Won: \(stayingCounter), Switching Won: \(switchingCounter)")
}
There's no tricks in the code. No gimmicks. So, the results?
Input | Staying Won | Switching Won |
---|---|---|
100 | 42 | 58 |
1000 | 344 | 656 |
10000 | 3289 | 6711 |
100000 | 33203 | 66797 |
1000000 | 333178 | 666822 |
10000000 | 3335146 | 6664854 |
It appears that Ben[1] was right. Taking the limit as the input get higher, switching won roughly $66\%$ of the time — compared that to the original $33\%$ you got before you were given the option to switch doors. So, how is this possible? I'll explain.
For simplicity, suppose the prize is behind door A out of doors A, B, C. The argument can be made for any initial door, but A makes it easier. At this point, you have $\frac{1}{3}$ chance of picking the prize no matter what you pick. If you pick door A, the door which contains the prize, the host will definitely want you to change so he will offer you either door B or C. Now suppose you choose a door without the prize, either door B or C. The host has no choice but to eliminate the door without the prize. Meaning if you switch, you have the winning door.
So, why $66\%$? Computationally, if you always switch and you picked the wrong door initially, your switch will win every time. There's two incorrect choices out of three, meaning $\frac{2}{3}$ of the time you will win.
You've just had your first lesson in conditional probability.
- 21 main character, played by Jim Sturgess ↩︎