"small footprint" C++ programs for STs?

GFA, ASM, STOS, ...

Moderators: simonsunnyboy, Mug UK, Zorro 2, Moderator Team

User avatar
mfro
Atari Super Hero
Atari Super Hero
Posts: 806
Joined: Thu Aug 02, 2012 10:33 am
Location: SW Germany

"small footprint" C++ programs for STs?

Postby mfro » Wed Feb 06, 2019 2:37 pm

a contradiction?

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 ;), as libcmini has just been made "C++ aware", i.e. it got all the missing symbols that prevented libstdc++ from linking properly before).

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!
Last edited by mfro on Wed Feb 06, 2019 6:12 pm, edited 1 time in total.

czietz
Hardware Guru
Hardware Guru
Posts: 1004
Joined: Tue May 24, 2016 6:47 pm

Re: "small footprint" C++ programs for STs?

Postby czietz » Wed Feb 06, 2019 2:57 pm

Nice! Do exceptions work?

User avatar
mfro
Atari Super Hero
Atari Super Hero
Posts: 806
Joined: Thu Aug 02, 2012 10:33 am
Location: SW Germany

Re: "small footprint" C++ programs for STs?

Postby mfro » Wed Feb 06, 2019 3:35 pm

czietz wrote:Nice! Do exceptions work?


As far as I have tested, yes. But - as we all know - nothing comes for free; exceptions, in this case, with a penalty of about 45KB:

Code: Select all

class myexception : public std::exception {
        virtual const char *what() const throw()
        {
            return "My exception happened";
        }
} e;

...

throw e;


What's way more interesting IMHO is TMP (template meta programming - within the limits of C++ 0x). The program above can easily be rewritten to build up the entire squares array at compile time at nearly no extra cost (but lots of runtime gain, of course):

Code: Select all

template <int16_t i> struct squared {
        squared <i - 1> rest;
        int16_t x;
        squared() : x((i - 1) * (i - 1)) { }

        // make some nice support for array notation
        int16_t& operator[](int16_t &index) {
           return reinterpret_cast<int16_t *>(this)[index];
        }
    };
   
    template <> struct squared<1> {
        int16_t x;
   
        squared() : x(0) { }
    };
   
    ...
   
    squared<LAST> s;
   


(5877 Bytes)

User avatar
simonsunnyboy
Moderator
Moderator
Posts: 5121
Joined: Wed Oct 23, 2002 4:36 pm
Location: Friedrichshafen, Germany
Contact:

Re: "small footprint" C++ programs for STs?

Postby simonsunnyboy » Wed Feb 06, 2019 4:40 pm

Nice although I personally still prefer plain C. But maybe this will find use cases in porting other software over?
Simon Sunnyboy/Paradize - http://paradize.atari.org/

Stay cool, stay Atari!

1x2600jr, 1x1040STFm, 1x1040STE 4MB+TOS2.06+SatanDisk, 1xF030 14MB+FPU+NetUS-Bee

czietz
Hardware Guru
Hardware Guru
Posts: 1004
Joined: Tue May 24, 2016 6:47 pm

Re: "small footprint" C++ programs for STs?

Postby czietz » Wed Feb 06, 2019 5:38 pm

Which compiler are you using? I just tried your sample with Thorsten's gcc 8.2.1. libcmini was also pulled fresh from Github and compiled with gcc 8.2.1. However, the C++ compiler acts as if all standard C library functions are missing:

Code: Select all

$ m68k-atari-mint-g++ -std=c++0x -nostdlib -I./libcmini/build/include -o cpp.prg -O2 -fomit-frame-pointer -s ./libcmini/build/startup.o sample.cpp -L./libcmini/build/ -lgcc -lcmini -lstdc++ -lgcc
/opt/gcc8/usr/bin/../lib/gcc/m68k-atari-mint/8/../../../../m68k-atari-mint/bin/ld: /opt/gcc8/usr/bin/../lib/gcc/m68k-atari-mint/8/../../../../m68k-atari-mint/lib/libstdc++.a(locale.o):locale.o:(.text+0xc4): undefined reference to `strcmp'
/opt/gcc8/usr/bin/../lib/gcc/m68k-atari-mint/8/../../../../m68k-atari-mint/bin/ld: /opt/gcc8/usr/bin/../lib/gcc/m68k-atari-mint/8/../../../../m68k-atari-mint/lib/libstdc++.a(locale.o):locale.o:(.text+0x4f8): undefined reference to `strcmp'
/opt/gcc8/usr/bin/../lib/gcc/m68k-atari-mint/8/../../../../m68k-atari-mint/bin/ld: /opt/gcc8/usr/bin/../lib/gcc/m68k-atari-mint/8/../../../../m68k-atari-mint/lib/libstdc++.a(locale.o):locale.o:(.text+0x5e8): undefined reference to `memcmp'


This goes on and on.

czietz
Hardware Guru
Hardware Guru
Posts: 1004
Joined: Tue May 24, 2016 6:47 pm

Re: "small footprint" C++ programs for STs?

Postby czietz » Wed Feb 06, 2019 5:45 pm

PS: Same issue with Vincent's g++ 4.6.4. I must be doing something fundamentally wrong.

User avatar
mfro
Atari Super Hero
Atari Super Hero
Posts: 806
Joined: Thu Aug 02, 2012 10:33 am
Location: SW Germany

Re: "small footprint" C++ programs for STs?

Postby mfro » Wed Feb 06, 2019 6:03 pm

Yes, my mistake, sorry.

the compiler command line must have libcmini after libstdc++:

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

(fixed above as well)

I used Vincent's compiler (thus the -std=c++0x as 4.6.4 supported only a subset of the then new C++ extensions). If you use 8.x, you might be able to use all the newer C++ features as well (but might also run into new problems, as I haven't tested this).

[edit: I just pushed the example (including a Makefile) to github: https://github.com/mfro0/libcmini-TMP ]

czietz
Hardware Guru
Hardware Guru
Posts: 1004
Joined: Tue May 24, 2016 6:47 pm

Re: "small footprint" C++ programs for STs?

Postby czietz » Wed Feb 06, 2019 6:43 pm

Thank you. From my very basic tests with gcc 8.2.1 (and C++17): When using <iostream>, some functions from libstdc++ get included that require the is...() type of functions from ctype.h (isalpha, isspace, ispunct, etc...) and therefore the program fails to link with libcmini.

mikro
Hardware Guru
Hardware Guru
Posts: 2034
Joined: Sat Sep 10, 2005 11:11 am
Location: Kosice, Slovakia
Contact:

Re: "small footprint" C++ programs for STs?

Postby mikro » Thu Feb 07, 2019 7:04 am

czietz wrote:Thank you. From my very basic tests with gcc 8.2.1 (and C++17): When using <iostream>, some functions from libstdc++ get included that require the is...() type of functions from ctype.h (isalpha, isspace, ispunct, etc...) and therefore the program fails to link with libcmini.

You may want to look at https://bitbucket.org/nokturnal/atari-gcc-startup/src by Saulot. His project predates libcmini (AFAIK) and has support for C++.

czietz
Hardware Guru
Hardware Guru
Posts: 1004
Joined: Tue May 24, 2016 6:47 pm

Re: "small footprint" C++ programs for STs?

Postby czietz » Thu Feb 07, 2019 7:14 am

mikro wrote:You may want to look at https://bitbucket.org/nokturnal/atari-gcc-startup/src by Saulot. His project predates libcmini (AFAIK) and has support for C++.


From what I can see, it doesn't have is...() as functions, either. It has macros in ctype.h, much like libcmini, but macros won't help the linker.

User avatar
mfro
Atari Super Hero
Atari Super Hero
Posts: 806
Joined: Thu Aug 02, 2012 10:33 am
Location: SW Germany

Re: "small footprint" C++ programs for STs?

Postby mfro » Thu Feb 07, 2019 8:27 am

Tried to install Thorsten Otto's gcc 8.1 for cygwin but failed.

It compiles fine but tries to assemble using the native (i686-pc-cygwin) assembler for some reason.
Not only that, it seems it also wrecked my existing 4.6.4 installation.
It appears now it's my turn doing something fundamentally wrong (or maybe it's just my personal Windows hypersensitivity)? :lol:

czietz
Hardware Guru
Hardware Guru
Posts: 1004
Joined: Tue May 24, 2016 6:47 pm

Re: "small footprint" C++ programs for STs?

Postby czietz » Thu Feb 07, 2019 8:51 am

For this reason, I didn't install Thorsten's gcc 8 into /usr/bin et al. under my Cygwin installation but into /opt/gcc/usr/... It works in that way, assuming I adjust PATH, and it doesn't interfere with other stuff.

ThorstenOtto
Atari Super Hero
Atari Super Hero
Posts: 793
Joined: Sun Aug 03, 2014 5:54 pm

Re: "small footprint" C++ programs for STs?

Postby ThorstenOtto » Thu Feb 07, 2019 11:33 am

czietz wrote:I didn't install Thorsten's gcc 8 into /usr/bin et al. under my Cygwin installation but into /opt/gcc/usr/... It works in that way, assuming I adjust PATH, and it doesn't interfere with other stuff.


Actually, on linux, i use it in a similar way. I leave the binaries where i compiled them (somewhere in my home directory), and /usr/bin/m68k-atari-mint-gcc is the 4.6.4 version. That way, the older version is used when i compile emutos or mint, because that still seems to be what everybody else uses, and it is easier to compare the results. When i do tests with newer gcc, i just change PATH. Both use the same libraries and include files from /usr/m68k-atari-mint.

mfro wrote:It compiles fine but tries to assemble using the native (i686-pc-cygwin) assembler for some reason.


Most of the time, this happens because it does not find the cross-assembler, and then invokes plain "as". The cross-compiler looks up the tools with a relative path as {directory of gcc}/../m68k-atari-mint/bin/as. When i run gcc from a different path, i create that ../m68k-atari-mint/bin directory, and put symlinks in it that point to eg. as -> /usr/bin/m68k-atari-mint-as (you can use the same binutils for all compilers, provided they are new enough). BTW. on cygwin & NTFS, you can also use native symlinks of the filesystem that also work e.g. when running a MINGW shell only.

User avatar
mfro
Atari Super Hero
Atari Super Hero
Posts: 806
Joined: Thu Aug 02, 2012 10:33 am
Location: SW Germany

Re: "small footprint" C++ programs for STs?

Postby mfro » Thu Feb 07, 2019 12:43 pm

ThorstenOtto wrote:... Both use the same libraries and include files from /usr/m68k-atari-mint...


This will most likely not fit our specific purpuse here as the new compiler comes with its own c++ include directory that needs to fit to the corresponding libstdc++.a to really use new c++ features?

ThorstenOtto
Atari Super Hero
Atari Super Hero
Posts: 793
Joined: Sun Aug 03, 2014 5:54 pm

Re: "small footprint" C++ programs for STs?

Postby ThorstenOtto » Thu Feb 07, 2019 12:52 pm

It does fit: gcc 7.x and gcc 8.x have their own directories /usr/include/c++/7 and /usr/include/c++/8, and the libraries can be put in {gccdir}/../m68k-atari-mint/lib

User avatar
mfro
Atari Super Hero
Atari Super Hero
Posts: 806
Joined: Thu Aug 02, 2012 10:33 am
Location: SW Germany

Re: "small footprint" C++ programs for STs?

Postby mfro » Thu Feb 07, 2019 1:02 pm

ThorstenOtto wrote:It does fit: gcc 7.x and gcc 8.x have their own directories /usr/include/c++/7 and /usr/include/c++/8, and the libraries can be put in {gccdir}/../m68k-atari-mint/lib


Thank you - right you are (as I just checked).

User avatar
sqward
Obsessive compulsive Atari behavior
Obsessive compulsive Atari behavior
Posts: 110
Joined: Wed Mar 12, 2008 4:47 pm
Location: London
Contact:

Re: "small footprint" C++ programs for STs?

Postby sqward » Sun Feb 10, 2019 10:49 pm

simonsunnyboy wrote:Nice although I personally still prefer plain C. But maybe this will find use cases in porting other software over?

My demos are written mainly in c++, so it's very useful on TOS platforms.

BlankVector
Captain Atari
Captain Atari
Posts: 483
Joined: Wed Oct 24, 2007 7:52 pm
Location: France
Contact:

Re: "small footprint" C++ programs for STs?

Postby BlankVector » Mon Mar 18, 2019 10:26 am

mfro wrote: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++.

Definitely! And this was even my main goal when I started working on the cross-tools.
I got very encouraging success by using no "new", no exceptions, no RTTI, and sometimes templates. Still a lot of useful features, and very compact and optimal code.
Subscribe to my Vretrocomputing channel on YouTube and Facebook. Latest video: Display a picture in assembly language on Atari ST.


Social Media

     

Return to “Coding”

Who is online

Users browsing this forum: No registered users and 2 guests