到底是什么会迫使 C++调用这个函数?

发布于 2024-08-13 02:44:21 字数 3378 浏览 6 评论 0原文

我正在开发一种编程语言,目前使用 C++ 作为目标语言。我遇到了一个异常奇怪的回溯。

#1  0x08048d09 in factorial (n=0x8052160) at ir.cpp:35
35      shore::builtin__int * __return = NULL;
(gdb) bt
#0  shore::builtin__int::__mul__ (this=0x8052160, other=0x8052288) at /home/alex/projects/shore/shore/runtime/int.h:36
#1  0x08048d09 in factorial (n=0x8052160) at ir.cpp:35
#2  0x08048cfa in factorial (n=0x80520b8) at ir.cpp:35
#3  0x08048cfa in factorial (n=0x8052018) at ir.cpp:35
#4  0x08048d6f in main () at ir.cpp:43

具体来说,声明 return 的类型似乎在某种程度上触发了builtin__int 上的 __mul 方法被调用,我不知道为什么。 builtin__int 看起来像:

#ifndef _SHORE_INT_H
#define _SHORE_INT_H

#include "gc.h"


namespace shore {
    class builtin__int : public shore::Object {
        public:
            // Some day this will be arbitrary percision, but not today.
            long long value;

            static builtin__int* new_instance(long long value_) {
                builtin__int* val = new builtin__int(value_);
                shore::GC::register_object(val);
                return val;
            }

            builtin__int(long long value_) {
                this->value = value_;
            }

            builtin__bool* __eq__(builtin__int* other) {
                return builtin__bool::new_instance(this->value == other->value);
            }

            builtin__int* __add__(builtin__int* other) {
                return builtin__int::new_instance(this->value + other->value);
            }

            builtin__int* __sub__(builtin__int* other) {
                return builtin__int::new_instance(this->value - other->value);
            }

            builtin__int* __mul__(builtin__int* other) {
                return builtin__int::new_instance(this->value * other->value);
            }
    };
}
#endif

关于到底是什么迫使 C++ 调用 mul 方法有什么想法吗?

编辑:添加了 ir.cpp 的源

#include "builtins.h"
#include "frame.h"
#include "object.h"
#include "state.h"
std::vector < shore::Frame * >shore::State::frames;
shore::GCSet shore::GC::allocated_objects;
class
    factorial__frame:
    public
    shore::Frame {
  public:
    shore::builtin__int *
    n;
    shore::GCSet
    __get_sub_objects() {
    shore::GCSet s;
    s.
    insert(this->n);
    return
        s;
}};
class
    main__frame:
    public
    shore::Frame {
  public:
    shore::GCSet
    __get_sub_objects() {
    shore::GCSet s;
    return
        s;
}};
shore::builtin__int * factorial(shore::builtin__int * n)
{
    shore::builtin__int * __return = NULL;
    factorial__frame frame;
    shore::State::frames.push_back(&frame);
    frame.n = NULL;
    frame.n = n;
    if (((frame.n)->__eq__(shore::builtin__int::new_instance(0)))->value) {
    __return = shore::builtin__int::new_instance(1);
    shore::GC::collect();
    shore::State::frames.pop_back();
    return __return;
    }
    __return =
    (frame.n)->
    __mul__(factorial
        ((frame.n)->
         __sub__(shore::builtin__int::new_instance(1))));
    shore::GC::collect();
    shore::State::frames.pop_back();
    return __return;
}
int
main()
{
    main__frame     frame;
    shore::State::frames.push_back(&frame);
    builtin__print(factorial(shore::builtin__int::new_instance(3)));
    shore::State::frames.pop_back();
}

I'm working on a programming language that uses C++ as it's target language for now. I'm hitting an exceptionally strange backtrace.

#1  0x08048d09 in factorial (n=0x8052160) at ir.cpp:35
35      shore::builtin__int * __return = NULL;
(gdb) bt
#0  shore::builtin__int::__mul__ (this=0x8052160, other=0x8052288) at /home/alex/projects/shore/shore/runtime/int.h:36
#1  0x08048d09 in factorial (n=0x8052160) at ir.cpp:35
#2  0x08048cfa in factorial (n=0x80520b8) at ir.cpp:35
#3  0x08048cfa in factorial (n=0x8052018) at ir.cpp:35
#4  0x08048d6f in main () at ir.cpp:43

Specifically it appears that declaring the type of return is somehow triggering the __mul method on builtin__int to be called, and I have no idea why. builtin__int looks like:

#ifndef _SHORE_INT_H
#define _SHORE_INT_H

#include "gc.h"


namespace shore {
    class builtin__int : public shore::Object {
        public:
            // Some day this will be arbitrary percision, but not today.
            long long value;

            static builtin__int* new_instance(long long value_) {
                builtin__int* val = new builtin__int(value_);
                shore::GC::register_object(val);
                return val;
            }

            builtin__int(long long value_) {
                this->value = value_;
            }

            builtin__bool* __eq__(builtin__int* other) {
                return builtin__bool::new_instance(this->value == other->value);
            }

            builtin__int* __add__(builtin__int* other) {
                return builtin__int::new_instance(this->value + other->value);
            }

            builtin__int* __sub__(builtin__int* other) {
                return builtin__int::new_instance(this->value - other->value);
            }

            builtin__int* __mul__(builtin__int* other) {
                return builtin__int::new_instance(this->value * other->value);
            }
    };
}
#endif

Any ideas as to what on earth is compelling C++ to call the mul method?

EDIT: Added the source of ir.cpp

#include "builtins.h"
#include "frame.h"
#include "object.h"
#include "state.h"
std::vector < shore::Frame * >shore::State::frames;
shore::GCSet shore::GC::allocated_objects;
class
    factorial__frame:
    public
    shore::Frame {
  public:
    shore::builtin__int *
    n;
    shore::GCSet
    __get_sub_objects() {
    shore::GCSet s;
    s.
    insert(this->n);
    return
        s;
}};
class
    main__frame:
    public
    shore::Frame {
  public:
    shore::GCSet
    __get_sub_objects() {
    shore::GCSet s;
    return
        s;
}};
shore::builtin__int * factorial(shore::builtin__int * n)
{
    shore::builtin__int * __return = NULL;
    factorial__frame frame;
    shore::State::frames.push_back(&frame);
    frame.n = NULL;
    frame.n = n;
    if (((frame.n)->__eq__(shore::builtin__int::new_instance(0)))->value) {
    __return = shore::builtin__int::new_instance(1);
    shore::GC::collect();
    shore::State::frames.pop_back();
    return __return;
    }
    __return =
    (frame.n)->
    __mul__(factorial
        ((frame.n)->
         __sub__(shore::builtin__int::new_instance(1))));
    shore::GC::collect();
    shore::State::frames.pop_back();
    return __return;
}
int
main()
{
    main__frame     frame;
    shore::State::frames.push_back(&frame);
    builtin__print(factorial(shore::builtin__int::new_instance(3)));
    shore::State::frames.pop_back();
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

爱她像谁 2024-08-20 02:44:21

有点猜测:shore::builtin__int * __return = NULL;行中的初始化没有执行任何操作,因为它总是被覆盖。编译器完全有权 (a) 通过调用 __mul__ 的语句将其重新排序到分配 __return 的位置,然后 (b) 完全删除代码。但也许它在调试信息中留下了源代码行,并且链接器或 gdb 最终认为调用指令属于附近几条源代码行中的错误之一。

永远不要相信源调试,除非您也可以看到反汇编。编译语言——呸,骗人的。等等。

A bit of a guess: the initialization in the line shore::builtin__int * __return = NULL; does nothing, since it's always overwritten. The compiler would be perfectly entitled to (a) reorder it down to where __return is assigned, by the statement that does call __mul__ and then (b) remove the code entirely. But maybe it's left the source line in the debugging info, and either the linker or gdb has ended up thinking the call instruction belongs to the wrong one of the several source lines in the vicinity.

Never trust source debugging unless you can see the disassembly too. Compiled languages - bah, humbug. And so forth.

酒浓于脸红 2024-08-20 02:44:21

带双下划线的标识符名称被保留。您可能会与编译器生成的名称发生冲突。

Identifier names with double underscores are reserved. You could be colliding with a compiler-generated name.

不再见 2024-08-20 02:44:21

在我看来,翻译器失败了,不知何故,gcc(或其他)认为 shore::builtin__int 是某种类型的值,并且您试图将其乘以 __return,而不是将值 __return 声明为 shore 类型: :builtin__int *...

显然,如果这个东西正在编译,并且给你运行时错误,那么乘法给你的任何类型都是有效的 LHS...

Looks to me like the translator is failing, and somehow gcc (or whatever) is thinks that shore::builtin__int is a value of some kind, and you are trying to multiply it by __return, instead of declare the value __return as type shore::builtin__int *...

Obviously, if this thing is compiling at all, and giving you run-time errors, then whatever type the multiplication would give you is a valid LHS...

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文