不同编译器执行顺序不同

问题描述 投票:0回答:1

此代码在 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

显然我希望两个编译器输出相同的东西..是否应该不这样做?这是已知的事情还是我可以对此做些什么?

compiler-construction
1个回答
1
投票

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

© www.soinside.com 2019 - 2024. All rights reserved.