我在这里尝试一些怪异的东西.我正在尝试编写使用GNU的g ++编译的C++程序,但不依赖于libstdc ++ :)但似乎我需要它,因为即使是最基本的东西也需要它.
具有可配置功能集的libstdc ++是可以接受的.
我使用的命令是
g++ -nodefaultlibs -fno-rtti -fno-exceptions -lc
Run Code Online (Sandbox Code Playgroud)
没有libstdc ++,我得到:
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'
Run Code Online (Sandbox Code Playgroud)
这些不在libc中,那么是否有一个非常简单的libstdc ++来实现这些东西呢?
我想用这种方式构建的测试代码目前看起来像这样:
#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;
}
Run Code Online (Sandbox Code Playgroud)
小智 6
也许这个答案有点太晚了,但是......
在没有 libstdc++ 的情况下编写 C++ 程序很容易。我已经做了几十年了。只是避免与 libstdc++ 链接。这很简单:要么使用 gcc 代替 g++ 进行链接,要么提供一个只有 new、del 和一些其他函数的假 libstdc++。
下面是一个示例,说明如何使用围绕 malloc 的透明包装器替换基本的 libstdc++ 功能:
#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);
}
Run Code Online (Sandbox Code Playgroud)
现在把它放到一个名为 libstd--.cpp 的文件中,然后构建你自己的 libstdc++.a:
gcc -c -O libstdc--.cpp
ar crs libstdc++.a libstdc--.o
Run Code Online (Sandbox Code Playgroud)
然后你可以尝试一个简单的测试:
class A
{
int *x;
public:
A () { x = new int [10]; }
~A () { delete [] x; }
};
int main ()
{
A a;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
编译并查看链接的内容:
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)
Run Code Online (Sandbox Code Playgroud)
嘿,看,妈妈,没有 libstdc++!
作为替代方案,您可以通过使用 gcc 而不是 g++ 链接并通过在链接器命令行上提供 libstdc--.o 来避免使用伪造的 libstdc++,以便您的代码可以找到替换消息并删除。
是的,事情好像operator new并operator delete在C++中,的确规定不是在C,所以这将是荒谬的,让他们在运行时库对于C,而不是用来明确诊断不当调用一个用于C++(同为"纯虚"到纯虚方法,等等).如果链接整个可执行文件而没有动态库访问,链接器应该(希望 - 取决于C++运行时库的编码方式)选择您在代码中使用的标准C++库的最小部分(和您使用的C++特定功能越少 - 例如new暗示delete析构函数调用等等 - 当然,您避免拉入更大块库的机会就越大;-).
这是一个很好的解释:
http://www.trilithium.com/johan/2005/06/static-libstdc/
这篇文章更详细地解释了这一点,但这样做的一个关键原因是 C++ 特定的库往往不如基本的 libc 库稳定。这可能有助于减少依赖性问题。
| 归档时间: |
|
| 查看次数: |
7145 次 |
| 最近记录: |