此代码在 XCode 和 Visual Studio 中提供不同的输出:
#include <iostream>
using namespace std;
int f() {
cout << 'A';
return 1;
}
int main() {
cout << '.' << f();
return 0;
}
在 Visual Studio 中输出
A.1
在 XCode 中它输出
.A1
显然我希望两个编译器输出相同的东西..是否应该不这样做?这是已知的事情还是我可以对此做些什么?
MSVC 编译代码的方式显然与 GCC 不同。
通过 Godbolt 检查汇编代码(使用 x86-64 gcc 13.2 和 x64 msvc v19.38)显示 MSVC 生成以下汇编:
int f(void) PROC ; f
$LN3:
sub rsp, 40 ; 00000028H
mov dl, 65 ; 00000041H
lea rcx, OFFSET FLAT:std::basic_ostream<char,std::char_traits<char> > std::cout ; std::cout
call std::basic_ostream<char,std::char_traits<char> > & std::operator<<<std::char_traits<char> >(std::basic_ostream<char,std::char_traits<char> > &,char) ; std::operator<<<std::char_traits<char> >
mov eax, 1
add rsp, 40 ; 00000028H
ret 0
int f(void) ENDP ; f
tv69 = 32
main PROC
$LN3:
sub rsp, 56 ; 00000038H
call int f(void) ; f
mov DWORD PTR tv69[rsp], eax
mov dl, 46 ; 0000002eH
lea rcx, OFFSET FLAT:std::basic_ostream<char,std::char_traits<char> > std::cout ; std::cout
call std::basic_ostream<char,std::char_traits<char> > & std::operator<<<std::char_traits<char> >(std::basic_ostream<char,std::char_traits<char> > &,char) ; std::operator<<<std::char_traits<char> >
mov ecx, DWORD PTR tv69[rsp]
mov edx, ecx
mov rcx, rax
call std::basic_ostream<char,std::char_traits<char> > & std::basic_ostream<char,std::char_traits<char> >::operator<<(int) ; std::basic_ostream<char,std::char_traits<char> >::operator<<
xor eax, eax
add rsp, 56 ; 00000038H
ret 0
main ENDP
...GCC 产生这个:
f():
push rbp
mov rbp, rsp
mov esi, 65
mov edi, OFFSET FLAT:_ZSt4cout
call std::basic_ostream<char, std::char_traits<char> >& std::operator<< <std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char)
mov eax, 1
pop rbp
ret
main:
push rbp
mov rbp, rsp
push rbx
sub rsp, 8
mov esi, 46
mov edi, OFFSET FLAT:_ZSt4cout
call std::basic_ostream<char, std::char_traits<char> >& std::operator<< <std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char)
mov rbx, rax
call f()
mov esi, eax
mov rdi, rbx
call std::basic_ostream<char, std::char_traits<char> >::operator<<(int)
mov eax, 0
mov rbx, QWORD PTR [rbp-8]
leave
ret
在 MSVC 输出中,
f()
在第一个 operator<<
之前调用 before,而 GCC 在
f()
上调用第一个 operator<<
时调用 std::cout
after。