enum switchcase: sind gleiche variablen namen in der fallunterscheidung verboten? dürfen



  • Hallo,

    Ich will einen bytecode interpreter schreiben und das hier compiliert nicht mit 14 fehlermeldungen: es scheint, als ob es nicht möglich ist den gleichen variablen namen in den einzelnen switch cases zu benutzen. Außerdem kann nicht dorthin gesprungen werden, warum weiß ich nicht. Kann mir jemand helfen? Danke!

    error: cannot jump from switch statement to this case label
               default:
    
    error: redefinition of 'operand_A'
    double operand_A = pop();
    
    #ifndef GUARD_VM_h
    #define GUARD_VM_h
    #include <vector>
    
    enum status_code {
        OK, COMPILE_ERROR, RUNTIME_ERROR
    };
    
    enum op_code {
        OP_RETURN, OP_CONSTANT, OP_NEGATE,OP_ADD, OP_SUBTRACT, OP_MULTIPLY, OP_DIVIDE,
    };
    
    typedef std::vector<op_code> code_segment;
    typedef std::vector<double> constant_segment;
    typedef std::vector<uint64_t> code_lines;
    
    class VM {
    
        uint64_t ip;
        uint64_t sp;
        code_segment code;
        constant_segment constants;
        code_lines code_lines;
        std::vector<double> stack;
        public:
            status_code run();
    
            void print_stack_trace();
            
            uint64_t push(double val);
    
            double pop();
    
            int write_to_constants(double constant);
    
            void write_constant_to_code(double constant);
    
            void write_opcode(op_code operation);
    };
    
    #endif
    
    
    #include "vm.h"
    #include <vector>
    #include <iostream>
    
    status_code VM::run(){
        for(;;){
            switch(code[ip++]){
                case OP_RETURN:
                    std::cout << "stack.pop() " << pop() << std::endl;
                    return OK;
                    break;
                case OP_CONSTANT:
                    double constant = constants[code[ip++]];
                    push(constant);
                    std::cout << "op_constant on stack:" << constant << std::endl;
                    break;
                case OP_NEGATE:
                    double constant = constants[code[ip++]];
                    push(-constant);
                    std::cout << "op_negate on stack:" << constant << std::endl;
                    break;
                case OP_MULTIPLY:
                    double operand_B = pop();
                    double operand_A = pop();
                    push(operand_A * operand_B);
                    break;
                case OP_ADD:
                    double operand_B = pop();
                    double operand_A = pop();
                    push(operand_A + operand_B);
                    break;
                case OP_SUBTRACT:
                //TODO: is the sequence correct?
                    double operand_B = pop();
                    double operand_A = pop();
                    push(operand_A - operand_B);
                    break;
                case OP_DIVIDE:
                    double operand_B = pop();
                    double operand_A = pop();
                    push(operand_A / operand_B);
                    break;
                default:
                    break;
            }
        }
    }
    

  • Mod

    Du musst über Gültigkeitsbereiche lernen!

    Unter der Annahme, dass die Variablen nur in ihrem jeweiligen Case benutzt werden: Mach um alle deine Blöcke {…}. So

    switch(blah)
    {
       case 1:
       {
         code1;
       }
      case 2:
      {
        code2;
      }
    }
    

    Das löst auch das Problem mit dem verbotenen Sprung, denn da dürfte die Ursache sein, dass die Variablen von weiter oben in einem undefinierten Zustand sind. Mit den Codeblöcken sind sie aber in einem genau definierten Zustand, nämlich nicht-existierend.



  • cool danke!
    es bleibt noch ein sehr kryptischer fehler, der an dem include von vector liegt:

    
    /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/c++/v1/__memory/allocator_traits.h:305:5: error: no matching function for call to '__construct_at'
        std::__construct_at(__p, std::forward<_Args>(__args)...);
    

  • Mod

    @fairy2211 sagte in enum switchcase: sind gleiche variablen namen in der fallunterscheidung verboten? dürfen:

    cool danke!
    es bleibt noch ein sehr kryptischer fehler, der an dem include von vector liegt:

    Was? Ein Programm

    #include<vector>
    int main(){}
    

    wirft bei dir diesen Fehler?



  • @SeppJ mein Makefile:
    Also ja, aber nicht die main.cpp an sich sondern das include von vector scheint das problem zu sein.

    main: main.cpp vm.h vm.cpp
    	g++ -std=c++20 main.cpp vm.cpp -o main
    
    #include "vm.h"
    #include "test_vm.h"
    #include <string>
    using namespace std;
    
    int main(){
        string s = "test hello world \n run hello world";
        
        //test_binary_numeric_ops();
        return 0;
    }
    

  • Mod

    Bitte nicht herumraten. Wenn

    #include<vector>
    int main(){}
    

    den Fehler nicht zeigt, wie kommst du dann zu der Annahme, es läge am #include<vector>?

    Die Fehlermeldung klingt eher danach, als würdest du etwas in einen Vector pushen wollen, das da nicht hinein passt. Aber den dafür relevanten Code zeigst du uns nicht. Noch wird das die vollständige Fehlermeldung sein. Siehe hier: Du brauchst Hilfe? Besonders den zweiten Teil über nachvollziehbare Problembeschreibungen.

    PS: Du machst immer noch C mit cout. Mit der push-Funktion würde ich sogar sagen, es ist schlimmer geworden seit dem ich dich darauf aufmerksam gemacht habe, und es ist nun Assembler mit cout. Kein Wunder, dass du da selber nicht mehr durchfindest. Gerade als Anfänger tödlich, da du mit den allgemeinen Grundlagen Probleme hast, und dann auch noch selbstgemachtes Chaos einführst.



  • @SeppJ sagte in enum switchcase: sind gleiche variablen namen in der fallunterscheidung verboten? dürfen:

    den Fehler nicht zeigt, wie kommst du dann zu der Annahme, es läge am #include<vector>?

    also die fehlermeldung fängt mit dem include in vm.h an und die erste klasse, die nicht von mir ist, ist vector. Ich verstehe nicht ganz, was du mit C mit cout meinst - nicht nutzen von der std:: library z.B. und von der Objektorientierung? Was push angeht habe ich ja schon gesagt, dass es mMn nicht anders geht.

    
    In file included from vm.cpp:1:
    In file included from ./vm.h:3:
    In file included from /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/c++/v1/vector:325:
    

    Ich weiß, dass man z.B. eine <queue> benutzen kann. Das problem hierbei war allerdings, dass man über elemente in der queue nicht iterieren konnte. Deshalb habe ich einen vector statt queue benutzt.
    Ich habe deinen Tipp beherzigt und eine Klasse daraus gemacht.


  • Mod

    ...



  • @SeppJ hahahaha ich habe gerade noch mal meinen Post durchgelesen, sorry. Ich habe ihn editiert. Ich habe meine erste Zeile zu deinem Zitat zugefügt, deshalb konnte man das nicht lesen.



  • @fairy2211 sagte in enum switchcase: sind gleiche variablen namen in der fallunterscheidung verboten? dürfen:

    @SeppJ hahahaha ich habe gerade noch mal meinen Post durchgelesen, sorry. Ich habe ihn editiert.

    Ich verstehe immer noch nicht, was du damit sagen willst.
    Bitte nachvollziehbar beschreiben, d.h. mit vollständiger Fehlermeldung (und nicht deiner Interpretation der Fehlermeldung) und dem relevanten Codeteil.

    Das "C mit cout" ist erstmal völlig unabhängig vom konkreten Fehler. Damit will @SeppJ nur den Programmierstil kritisieren. Das ist also ein anderes Problem als die konkrete Fehlermeldung. - Das ist zwar auch relevant, aber vielleicht sollten wir uns hier auf 1 Sache zur Zeit konzentrieren.

    Du kannst dir sehr sicher sein, dass #include <vector> NICHT die Ursache deines Problems ist. Wie schon gesagt, benutzt du vector falsch oder der Fehler liegt noch anderswo. Aber nicht am vector-include!


Anmelden zum Antworten