gpt4 book ai didi

c++ - "pure virtual function called"在 gcc 4.4 上,但不在新版本或 clang 3.4 上

转载 作者:IT老高 更新时间:2023-10-28 23:18:18 25 4
gpt4 key购买 nike

我有一个 MCVE,它在使用 g++ 4.4.7 版编译时在我的一些机器上崩溃,但可以在 clang++ 3.4.2 版和 g++ 6.3 版中使用。

我想知道它是来自未定义的行为还是来自这个古老版本的 gcc 的实际错误。

代码

#include <cstdlib>

class BaseType
{
public:
BaseType() : _present( false ) {}
virtual ~BaseType() {}

virtual void clear() {}

virtual void setString(const char* value, const char* fieldName)
{
_present = (*value != '\0');
}

protected:
virtual void setStrNoCheck(const char* value) = 0;

protected:
bool _present;
};

// ----------------------------------------------------------------------------------

class TypeTextFix : public BaseType
{
public:
virtual void clear() {}

virtual void setString(const char* value, const char* fieldName)
{
clear();
BaseType::setString(value, fieldName);
if( _present == false ) {
return; // commenting this return fix the crash. Yes it does!
}
setStrNoCheck(value);
}

protected:
virtual void setStrNoCheck(const char* value) {}
};

// ----------------------------------------------------------------------------------

struct Wrapper
{
TypeTextFix _text;
};

int main()
{
{
Wrapper wrapped;
wrapped._text.setString("123456789012", NULL);
}
// if I add a write to stdout here, it does not crash oO
{
Wrapper wrapped;
wrapped._text.setString("123456789012", NULL); // without this line (or any one), the program runs just fine!
}
}

编译运行

g++ -O1 -Wall -Werror thebug.cpp && ./a.out
pure virtual method called
terminate called without an active exception
Aborted (core dumped)

这实际上是最小的,如果删除此代码的任何功能,它就可以正常运行。

分析

代码片段在使用 -O0 编译时可以正常工作,BUT 在每个标志使用 -O0 +flag 编译时仍然可以正常工作GnuCC documentation 上定义的 -O1

生成一个核心转储,可以从中提取回溯:

(gdb) bt
#0 0x0000003f93e32625 in raise () from /lib64/libc.so.6
#1 0x0000003f93e33e05 in abort () from /lib64/libc.so.6
#2 0x0000003f98ebea7d in __gnu_cxx::__verbose_terminate_handler() () from /usr/lib64/libstdc++.so.6
#3 0x0000003f98ebcbd6 in ?? () from /usr/lib64/libstdc++.so.6
#4 0x0000003f98ebcc03 in std::terminate() () from /usr/lib64/libstdc++.so.6
#5 0x0000003f98ebd55f in __cxa_pure_virtual () from /usr/lib64/libstdc++.so.6
#6 0x00000000004007b6 in main ()

请随时在评论中询问测试或详细信息。问:

  • 实际代码吗?是的!这是!一个字节一个字节。我已经检查并重新检查了。

  • 您使用的是哪个版本的 GnuCC?

    $ g++ --version
    g++ (GCC) 4.4.7 20120313 (Red Hat 4.4.7-16)
    Copyright (C) 2010 Free Software Foundation, Inc.
    This is free software; see the source for copying conditions. There is NO
    warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  • 我们能看到生成的程序集吗?是的,here it is on pastebin.com

最佳答案

这是 FSF GCC 中不存在的 Red Hat 特定错误。这不是您的代码中的问题。

在同时具有 CentOS 6 的 GCC 和 FSF GCC 4.4.7 的系统上,同时生成程序集列表并查看两者之间的差异,会跳出一点:

CentOS 6 的 GCC 生成

movq $_ZTV8BaseType+16, (%rsp)

而 FSF GCC 4.4.7 生成

movq $_ZTV11TypeTextFix+16, (%rsp)

换句话说,Red Hat 的 GCC 补丁之一导致它错误地设置了 vtable。这是您的 main 函数的一部分,您可以在 .L48: 之后不久在您自己的程序集 list 中看到它。

Red Hat 为其 GCC 版本应用了许多补丁,其中一些补丁是影响代码生成的补丁。不幸的是,其中一个似乎有意想不到的副作用。

关于c++ - "pure virtual function called"在 gcc 4.4 上,但不在新版本或 clang 3.4 上,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41810222/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com