c++ - 为什么 MSVC 会优化掉这个 memcpy 调用?

标签 c++ c

我有以下 C 代码(我将其缩短了一些其他调用和检查):

#include <stdint.h>
#include <memory.h>

extern char buffer[];

extern void getstr1(char *buff, int buflen);
extern void getstr2(char **s);
extern void dosomething(char *s);

void myfn()
{
    char *s, *s1;
    int len;

    getstr1(buffer, 128);
    getstr2(&s);

    len = *s + *buffer;
    memcpy(buffer + *buffer + 1, s + 1, (*s) * sizeof(char));
    *buffer = len;

    dosomething(buffer);
}

带有/O2 优化选项的 MSVC 产生以下输出:

_s$ = -4                                                ; size = 4
void myfn(void) PROC                                 ; myfn, COMDAT
        push    ecx
        push    128                           ; 00000080H
        push    OFFSET char * buffer             ; buffer
        call    void getstr1(char *,int)           ; getstr1
        lea     eax, DWORD PTR _s$[esp+12]
        push    eax
        call    void getstr2(char * *)                    ; getstr2
        mov     eax, DWORD PTR _s$[esp+16]
        push    OFFSET char * buffer             ; buffer
        mov     al, BYTE PTR [eax]
        add     BYTE PTR char * buffer, al
        call    void dosomething(char *)              ; dosomething
        add     esp, 20                             ; 00000014H
        ret     0
void myfn(void) ENDP                                 ; myfn

您可以查看 on Godbolt

为什么编译器忽略了 memcpy 调用?有趣的是,将外部变量声明为“extern char buffer[N];”其中 N >= 2 或作为“extern char *buffer;”使编译器使用 memcpy。也用 memmove 替换 memcpy 做同样的事情。当源区域和目标区域重叠时,我知道可能的 UB,但这里编译器不知道这一点。

最佳答案

我认为这是 MSVC 中的一个错误,因为您所做的事情是合法的。

请注意,已经提交了一个类似的错误,标题为:Release build with speed optimize leaves an array uninitialized .

在错误报告中给出的重现问题的代码也使用了一个extern type array[];

根据团队的说法,此问题已在即将发布的版本中修复(未提及)。

关于c++ - 为什么 MSVC 会优化掉这个 memcpy 调用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55398743/

相关文章:

c++ - 这个 C++ 头文件的布局方式有什么问题吗?

c++ - 如何在C++中转换为utf8字符串

c++ - 如何正确启动 C 和 C++ IAR 嵌入式项目?

c - 在函数中使用 srand()

c - 如何在 C 中的 unsigned char* 变量中存储可表示为 32 个十六进制字符的 16 字节二进制值

跨平台使用 fgets()?

c++ - 我可以将 c++ sanitizer 仅应用于我的程序部分而不是第三方库吗

c++ - C++ 中的类和对象......需要一些额外的固定装置

c - 在 Visual Studio 2010 中使用 conio2

c - C中的半固定,半动态数组