C++ 运行用G++;码头工人

C++ 运行用G++;码头工人,c++,docker,g++,compiler-optimization,C++,Docker,G++,Compiler Optimization,如果可执行文件在docker内部或主机上运行,则其行为会有所不同。但这只有在我们改变G++的优化级别时才会发生 编译器: g++(Ubuntu 7.3.0-27ubuntu1~18.04)7.3.0 我正在尝试执行以下代码: #include <cstdio> #include <cstring> int main() { int nOrd =3395; char cOrd[] = "003395"; char cAux2[256];

如果可执行文件在docker内部或主机上运行,则其行为会有所不同。但这只有在我们改变G++的优化级别时才会发生

编译器: g++(Ubuntu 7.3.0-27ubuntu1~18.04)7.3.0

我正在尝试执行以下代码:

#include <cstdio>
#include <cstring>
int main()
 {
    int nOrd =3395;
    char cOrd[] = "003395";
    char cAux2[256];    
    strcpy(cAux2, cOrd);
    int nRest = nOrd % 26;
    printf("BEFORE SPRINTF %s\n\n\n", cAux2);
    sprintf(cAux2, "%s%c", cAux2, (nRest+65));
    printf("AFTER SPRINTF %s\n\n\n", cAux2);
    return 0;
 }
我在主机上运行。产出如预期:

BEFORE SPRINTF 003395


AFTER SPRINTF 003395P
如果我使用此可执行文件创建一个映像并在docker内部运行,我有:

Docker版本18.09.4,内部版本d14af54266

Dockerfile:

FROM debian
RUN apt-get update && apt-get install -y \
   libssl-dev
COPY fast/ /usr/local/
ENTRYPOINT ["usr/local/FastCompile"]
$docker build-t快速编译

$docker运行快速编译

BEFORE SPRINTF 003395


AFTER SPRINTF P
如果我删除-Os并使用以下命令重新编译:

g++ -o FastCompile FastCompile.c -DNDEBUG -Os
g++ -o FastCompile FastCompile.c -DNDEBUG 
Docker内部的行为是正确的

所以,
这是码头工人的问题吗?还是预期的行为?

您的代码具有未定义的行为

sprintf(cAux2, "%s%c", cAux2, (nRest+65));
读取和写入同一对象。要解决此问题,您可以在通话中使用
跳线
,这样您就不会从缓冲区读取数据。那看起来像

sprintf(cAux2, "%s%c", cOrd, (nRest+65));

还请注意,
(nRest+65)
提供了一个
int
,而不是格式说明符所说的
char
。这也是未定义的行为。你需要把它转换成一个字符来修复它

sprintf(cAux2, "%s%c", cOrd, char(nRest+65));

由于格式字符串表示
%c
,但
(nRest+65)
int
,是否还有第二个未定义的行为?此代码段来自用Visual c++6编写的旧代码。我将重新实现它以删除未定义的行为。感谢