Background: when I'm not playing with my TOS machines, I sometimes play with (ARM based) microcontrollers. Recently, I discovered C++ as my new playground and saw that it is entirely possible (if not common already) to code µC programs in C++. Now I wanted to see if that isn't something the Atari world could benefit from as well.
Let's assume (just to have something practical to discuss about) we need a program that writes out the squares of 1..100.
Code: Select all
#include <iostream>
#include <cstdint>
#include <array>
#define LAST 101
struct squares {
std::array<uint16_t, LAST> arr;
squares(int num) {
for (int i = 0; i < LAST; i++)
{
arr[i] = i * i;
}
}
void printme() {
for (auto const &value: arr)
std::cout << value << ", ";
}
};
int main()
{
squares(100).printme();
}
a cute little C++ program, you may think, but the rude awakening comes when you look at the executable's size:
394567 bytes. Yes. Nearly 400KB. Stripped, already. You'd probably easily be able to write this in assembler with less than, say, 1000 bytes and could still leave the symbol table in...
(compiled with
Code: Select all
m68k-atari-mint-g++ -std=c++0x -o simple.prg -O2 -fomit-frame-pointer -s simple.cc
Let's see how we can bring that down.
First, we replace the std::cout call with printf(). iostreams have a lot of functionality we do not need here, let's see if this makes a difference. We replace printme() with:
Code: Select all
void printme() {
for (auto const &value: arr)
printf("%d, ", value);
}
117836 bytes. Not too bad, but still way too large for our taste.
Let's try libcmini (yes, that's the sole reason I wrote this post, actually

Code: Select all
m68k-atari-mint-g++ -std=c++0x -nostdlib -I../libcmini/build/include -o simple.prg -O2 -fomit-frame-pointer -s ../libcmini/build/startup.o simple.cc -L../libcmini/build -lgcc -lstdc++ -lcmini -lgcc
The compiler command line became more complicated - this is to replace the mintlib startup code with libcmini's, set the include path to libcmini's include folder, avoid linking the standard libraries, make sure __main() in libgcc is called (that's why -lgcc appears twice, which is not strictly needed for this program but gives ugly errors if you have global initializers and it's not there) and link the libcmini lib.
12736 bytes. But we can do even better. libcmini's printf() routine is still a bit overqualified for what we do here. Let's replace printme() again:
Code: Select all
void printme() {
char outstr[30];
for (auto const &value: arr)
{
itoa(value, outstr, sizeof(outstr) - 1, 10);
Cconws(outstr); Cconws(", ");
}
}
Now we end up at 5145 bytes - with the exact same functionality we started with. At about 1/80th of the size and totally appropriate for a TOS program even on a 512k machine.
Happy C++ing!