C++ 从源代码构建的Clang编译C而不是C++;代码
我最近在windows上编译了clang(主机:x86_64-pc-windows64;编译器:i686-pc-mingw32;目标:i686-pc-mingw32)。C++ 从源代码构建的Clang编译C而不是C++;代码,c++,c,windows,mingw,clang,C++,C,Windows,Mingw,Clang,我最近在windows上编译了clang(主机:x86_64-pc-windows64;编译器:i686-pc-mingw32;目标:i686-pc-mingw32)。 可以找到CMakeCache(用于配置): 我的问题是,虽然clang(对于C)工作正常,但clang++(对于C++)将“成功”编译和链接,但生成的程序本身不会运行,并且将退出,并返回错误代码1。下面是一个示例(哦,我的zsh): ➜ 箱猫试验 #包括 int main() { printf(“你好,世界!\n”); 返回0
可以找到CMakeCache(用于配置):
我的问题是,虽然clang(对于C)工作正常,但clang++(对于C++)将“成功”编译和链接,但生成的程序本身不会运行,并且将退出,并返回错误代码1。下面是一个示例(哦,我的zsh):
➜ 箱猫试验
#包括
int main()
{
printf(“你好,世界!\n”);
返回0;
}
➜ bin cat test.cpp
#包括
int main()
{
std::cout您的新clang使用了不同的(不正确),而不是x86\u thiscallcc
snap.s
来自好的叮当声:
movl $__ZStL8__ioinit, %ecx
calll __ZNSt8ios_base4InitC1Ev
movl %esp, %ecx
movl $__ZSt4endlIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_, (%ecx)
movl %eax, %ecx
calll __ZNSolsEPFRSoS_E
与您的自定义密码相同,comp.s
:
leal __ZStL8__ioinit, %eax
movl %eax, (%esp)
calll __ZNSt8ios_base4InitC1Ev
movl %eax, (%esp)
movl %ecx, 4(%esp)
calll __ZNSolsEPFRSoS_E
和其他几个
在llvm位代码(*.ll
文件)中,右调用约定在函数定义中和调用
指令之后标记为x86\u thiscallcc
:
< call void @_ZNSt8ios_base4InitC1Ev(%"class.std::ios_base::Init"* @_ZStL8__ioinit)
> call x86_thiscallcc void @_ZNSt8ios_base4InitC1Ev(%"class.std::ios_base::Init"* @_ZStL8__ioinit)
< declare void @_ZNSt8ios_base4InitC1Ev(%"class.std::ios_base::Init"*) #0
> declare x86_thiscallcc void @_ZNSt8ios_base4InitC1Ev(%"class.std::ios_base::Init"*) #0
32c33
< declare void @_ZNSt8ios_base4InitD1Ev(%"class.std::ios_base::Init"*) #0
> declare x86_thiscallcc void @_ZNSt8ios_base4InitD1Ev(%"class.std::ios_base::Init"*) #0
< call void @_ZNSt8ios_base4InitD1Ev(%"class.std::ios_base::Init"* @_ZStL8__ioinit)
> call x86_thiscallcc void @_ZNSt8ios_base4InitD1Ev(%"class.std::ios_base::Init"* @_ZStL8__ioinit)
< %3 = call %"class.std::basic_ostream"* @_ZNSolsEPFRSoS_E(%"class.std::basic_ostream"* %2, %"class.std::basic_ostream"* (%"class.std::basic_ostream"*)* @_ZSt4endlIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_)
> %call1 = call x86_thiscallcc %"class.std::basic_ostream"* @_ZNSolsEPFRSoS_E(%"class.std::basic_ostream"* %call, %"class.std::basic_ostream"* (%"class.std::basic_ostream"*)* @_ZSt4endlIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_)
< declare %"class.std::basic_ostream"* @_ZNSolsEPFRSoS_E(%"class.std::basic_ostream"*, %"class.std::basic_ostream"* (%"class.std::basic_ostream"*)*) #0
> declare x86_thiscallcc %"class.std::basic_ostream"* @_ZNSolsEPFRSoS_E(%"class.std::basic_ostream"*, %"class.std::basic_ostream"* (%"class.std::basic_ostream"*)*) #0
调用x86_thiscallcc void@_ZNSt8ios_base4InitC1Ev(%%“class.std::ios_base::Init”*@_ZStL8_ioinit)
声明x86_thiscallcc void@_ZNSt8ios_base4InitC1Ev(%“class.std::ios_base::Init”*)#0
32c33
声明x86_thiscallcc void@_ZNSt8ios_base4InitD1Ev(%“class.std::ios_base::Init”*)#0
调用x86_thiscallcc void@_ZNSt8ios_base4InitD1Ev(%%“class.std::ios_base::Init”*@_ZStL8_ioinit)
<%3=call%“class.std::basic_ostream”*@\u ZNSolsEPFRSoS\u E(%“class.std::basic_ostream”*%2、%“class.std::basic_ostream”*(“class.std::basic_ostream”*)*@\u ZSt4endlIcSt11char\u traitsicerst13basic_ostream\u T0\u ES6)
>%call1=call x86_thiscallcc%“class.std::basic_ostream”*@_ZNSolsEPFRSoS_E(%“class.std::basic_ostream”*%call,%“class.std::basic_ostream”*(“class.std::basic_ostream”*)*@"ZSt4endlIcSt11char traitsierst13basic_ostream(
声明x86_thiscallcc%“class.std::basic_ostream”*@_ZNSolsEPFRSoS_E(%“class.std::basic_ostream”*,%“class.std::basic_ostream”*(“class.std::basic_ostream”*)\0
在预处理的文件中,我看到了差异。在snap.E
中,许多函数是用\uuuu attribute\uuuu((\uuu cdecl\uuuu))
定义的,而在comp.E
中,它们是用\uu cdecl\uuuu
定义的。在预处理后,您应该检查定义为何不同。我认为,new clang可能会预先定义不同的宏集(gcc有-dM-E
选项来转储预定义的文件,不知道如何在clang中实现)。或者您的clang只是使用不同的头文件(或者不同版本的头文件,您可以使用clang编译的-H
选项列出使用过的头文件)
另一种方法是检查,is\uuuu属性((\uu-cdecl\uuuu))
应该等于\uu-cdecl\uuuu
,并且更新版本的clang在处理它们时是否会改变任何东西。您是否尝试过查看汇编程序或LLVM-IR输出(clang++-S test.cpp
或clang++-S-emit LLVM test.cpp
)看看它是否包含“异常”。你到底编译了哪一个源代码?都是.AXE是C++源代码(test .CPP)的结果;B.EXE是C源代码(test .c)的结果。C.不工作,C++不工作。CpA++-S测试。CP< <代码>不> Calang++-s -发射LVVM测试。CPP < /代码>产生任何输出。您应该得到一个名为test .s和Test.LL的文件。我只有一个Test.LL文件。我怀疑这是CLAN版本,因为3.4也在平台上工作。PS:CLAN 3.5的确切版本是什么?调用convention clang version 3.5(208017)有几个clang bug,所以有没有办法解决这个问题?(不去3.5,因为它(svn)在我的机器上编译得不好(还没有)。)请列出这两个完整版本,在这个问题中使用。
< call void @_ZNSt8ios_base4InitC1Ev(%"class.std::ios_base::Init"* @_ZStL8__ioinit)
> call x86_thiscallcc void @_ZNSt8ios_base4InitC1Ev(%"class.std::ios_base::Init"* @_ZStL8__ioinit)
< declare void @_ZNSt8ios_base4InitC1Ev(%"class.std::ios_base::Init"*) #0
> declare x86_thiscallcc void @_ZNSt8ios_base4InitC1Ev(%"class.std::ios_base::Init"*) #0
32c33
< declare void @_ZNSt8ios_base4InitD1Ev(%"class.std::ios_base::Init"*) #0
> declare x86_thiscallcc void @_ZNSt8ios_base4InitD1Ev(%"class.std::ios_base::Init"*) #0
< call void @_ZNSt8ios_base4InitD1Ev(%"class.std::ios_base::Init"* @_ZStL8__ioinit)
> call x86_thiscallcc void @_ZNSt8ios_base4InitD1Ev(%"class.std::ios_base::Init"* @_ZStL8__ioinit)
< %3 = call %"class.std::basic_ostream"* @_ZNSolsEPFRSoS_E(%"class.std::basic_ostream"* %2, %"class.std::basic_ostream"* (%"class.std::basic_ostream"*)* @_ZSt4endlIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_)
> %call1 = call x86_thiscallcc %"class.std::basic_ostream"* @_ZNSolsEPFRSoS_E(%"class.std::basic_ostream"* %call, %"class.std::basic_ostream"* (%"class.std::basic_ostream"*)* @_ZSt4endlIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_)
< declare %"class.std::basic_ostream"* @_ZNSolsEPFRSoS_E(%"class.std::basic_ostream"*, %"class.std::basic_ostream"* (%"class.std::basic_ostream"*)*) #0
> declare x86_thiscallcc %"class.std::basic_ostream"* @_ZNSolsEPFRSoS_E(%"class.std::basic_ostream"*, %"class.std::basic_ostream"* (%"class.std::basic_ostream"*)*) #0