C++ 从源代码构建的Clang编译C而不是C++;代码

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

我最近在windows上编译了clang(主机:x86_64-pc-windows64;编译器:i686-pc-mingw32;目标:i686-pc-mingw32)。
可以找到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