Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

g++ without libstdc++ - can it be done? - a very configurable lightweight libstdc++ where I can take stuff out easily would also do the trick

Tags:

c++

libstdc++

I'm trying something spooky here. I'm trying to write C++ programs, compiled with GNU's g++, but without a dependency on libstdc++ :) but it seems that I need that for even the most basic things need it.

A libstdc++ with a configurable feature set would be acceptable.

The command I use is

g++ -nodefaultlibs -fno-rtti -fno-exceptions -lc

Without libstdc++, I get:

undefined reference to `operator delete(void*)'  
undefined reference to `operator new(unsigned int)'  
undefined reference to `vtable for __cxxabiv1::__class_type_info'  
undefined reference to `vtable for __cxxabiv1::__si_class_type_info'  
undefined reference to `__cxa_pure_virtual'

These aren't in libc, so is there a really light libstdc++ that implements just these things?

My test code which I want to build this way currently looks like this:

#include <stdio.h>

template <class T>
class X
{
    public:
    T a;
};

class A1
{
    public:
        virtual void f() = 0;
        virtual ~A1() {}
};

class A2 : public A1
{
    public:
        virtual void f() {};
        virtual ~A2() {}
};

class Y
{
    public:
        ~Y() {}
};

int main()
{
    X<int> A;
    X<float> B;
    Y *C = new Y;

    A.a = 12;
    B.a = 2.3;

    printf("A: %d; B: %f\n", A.a, B.a);

    A2 *a2 = new A2;
    a2->f();

    return 0;
}
like image 632
Radu C Avatar asked Sep 15 '10 01:09

Radu C


2 Answers

Yes, things like operator new and operator delete are indeed defined in C++, not in C, so it would be absurd to have them in the runtime library for C as opposed to the one for C++ (same for the "pure virtual" used to clearly diagnose wrongful calls to pure virtual methods, and so on). If you link your whole executable without dynamic library access, the linker should (one hopes -- depending on how modularly the C++ runtime library is coded) pick and choose the bare minimum portion of the standard C++ library that you use in your code (and the fewer C++ specific features you use -- such as new implying delete for destructor calls, and so forth -- the greater your chances to avoid pulling in larger chunks of the library, of course;-).

like image 134
Alex Martelli Avatar answered Sep 20 '22 14:09

Alex Martelli


Maybe this answer is a bit too late, but...

Writing c++ programs without libstdc++ is easy. I'm doing it for decades. Just avoid linking with libstdc++. That's easy: either use gcc for linking instead of g++, or provide a fake libstdc++ with only new, del and a few other functions.

Here's a example how you can replace the basic libstdc++ functionality with a transparent wrapper around malloc:

#include <stdlib.h>

// MSVC uses __cdecl calling convention for new/delete :-O
#ifdef _MSC_VER
#  define NEWDEL_CALL __cdecl
#else
#  define NEWDEL_CALL
#endif

extern "C" void __cxa_pure_virtual ()
{
    abort ();
}

void * NEWDEL_CALL operator new (size_t size)
{
    return malloc (size);
}

void * NEWDEL_CALL operator new [] (size_t size)
{
    return malloc (size);
}

void NEWDEL_CALL operator delete (void *p)
{
    if (p) free (p);
}

void NEWDEL_CALL operator delete [] (void *p)
{
    if (p) free (p);
}

void NEWDEL_CALL operator delete (void *p, size_t)
{
    if (p) free (p);
}

Now put that into a file named, say, libstd--.cpp, and build your own libstdc++.a:

gcc -c -O libstdc--.cpp
ar crs libstdc++.a libstdc--.o

Then you can try a simple test:

class A
{
    int *x;

public:
    A () { x = new int [10]; }
    ~A () { delete [] x; }
};

int main ()
{
    A a;
    return 0;
}

Compile and look what's got linked:

g++ -g test.cpp -o test -L.

# ldd ./test
    linux-vdso.so.1 (0x00007ffed0b8d000)
    libm.so.6 => /lib64/libm.so.6 (0x00007f4d18df0000)
    libgcc_s.so.1 => /lib64/libgcc_s.so.1 (0x00007f4d18bd9000)
    libc.so.6 => /lib64/libc.so.6 (0x00007f4d18823000)
    /lib64/ld-linux-x86-64.so.2 (0x00007f4d1913b000)

Hey, look, ma, no libstdc++!

As an alternative, you may avoid using a fake libstdc++ by linking with gcc instead of g++ and by providing libstdc--.o on the linker command line so that your code may find the replacement news and deletes.

like image 40
Andrey Zabolotnyi Avatar answered Sep 18 '22 14:09

Andrey Zabolotnyi