O que na terra que compell C ++ para chamar esta função?
-
11-09-2019 - |
Pergunta
Eu estou trabalhando em uma linguagem de programação que usa C ++ como é língua-alvo por agora. Eu estou batendo um backtrace excepcionalmente estranho.
#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
Especificamente, parece que declarar o tipo de retorno é de alguma forma provocando a __mul método em builtin__int a ser chamado, e eu não tenho idéia do porquê. olhares builtin__int como:
#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
Todas as ideias sobre o que na terra é convincente C ++ para chamar o mul método?
EDIT: Adicionado a fonte de 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();
}
Solução
Um pouco de uma suposição: a inicialização no shore::builtin__int * __return = NULL;
linha não faz nada, uma vez que é sempre substituído. O compilador seria perfeitamente o direito de (a) reordenar-lo para onde __return
é atribuído, pela afirmação de que faz __mul__
chamada e depois (b) remover o código inteiramente. Mas talvez ele é deixado a linha de origem na informação de depuração, e quer o ligador ou gdb acabou pensando a instrução de chamada pertence à pessoa errada das várias linhas de código nas imediações.
fonte de confiança Nunca depurar a menos que você pode ver a desmontagem também. linguagens compiladas - Bah, farsa. E assim por diante.
Outras dicas
nomes de identificador com sublinhados duplos reservados. Você poderia estar colidindo com um nome gerado pelo compilador.
Parece-me que o tradutor está a falhar, e de alguma forma gcc (ou qualquer outro) é pensa que costa :: builtin__int é um valor de algum tipo, e que está a tentar multiplicá-lo por __return, em vez de declarar o valor __return como tipo costa :: builtin__int * ...
Obviamente, se essa coisa está compilando em tudo, e dando-lhe de tempo de execução erros, em seguida, digite qualquer que seja a multiplicação lhe daria é um LHS válidos ...