Check einer Konstanten auf Eindeutigkeit zur Compilezeit



  • @Miq sagte in Check einer Konstanten auf Eindeutigkeit zur Compilezeit:

    Da die Funktionscodes in der Library bisher als enum vorgegeben sind und die Methoden mit dem enum-Typ für Funktionscodes aufgerufen werden, um Fehler zu vermeiden, sind diese zusätzlichen Codes eigentlich nur aufzunehmen, wenn der Anwender im Librarycode das enum erweitert und die Library neu übersetzt.

    Um das zu vermeiden, suche ich nach einer Möglichkeit, die nach der Definition der Library-bekannten Funktionscodes verbleibenden, eigentlich illegalen Codes durch den Benutzer explizit auf den Typ ihrer nicht-Standard-Meldungen umzudefinieren und mit einem Namen zu versehen.

    Der Teil mit dem enum ist einfach zu beheben: gibt dem enum nen expliziten "underlying type":

    enum FunctionCode : uint8_t {
        FC_FOO = 0x11,
        FC_BAR = 0x22,
        // ...
    };
    
    void bar() {
        someFunction(static_cast<FunctionCode>(0x33));
    }
    

    Der Rest sollte auch nicht all zu schwer sein. In Frage kommende Lösungen hängen aber u.A. auch davon ab wie die Funktionen in deiner Library aussehen.

    Eine ganz einfache Möglichkeit könnte z.B. sein

    struct FooResult { ... };
    
    FooResult sendFooRequestCustom(FunctionCode code, int p1, int p2);
    
    inline FooResult sendFooRequest(int p1, int p2) {
        return sendFooRequestCustom(FC_FOO, p1, p2);
    }
    

    Benutzer mit "normalen" Geräten rufen dann sendFooRequest auf. Und Benutzer mit Geräten die einen "foo type" Request mit nem anderen Funktionscode haben können sendFooRequestCustom aufrufen und dabei den Funktionscode direkt angeben.



  • @Miq sagte in Check einer Konstanten auf Eindeutigkeit zur Compilezeit:

    @DocShoe sagte in Check einer Konstanten auf Eindeutigkeit zur Compilezeit:

    XY Problem

    Öh? Wenn ich nicht alle Details erwähnt habe, dann, um die Komplexität zu verringern, nicht, weil ich irgendwas verbergen wollte.

    Hast du nachgelesen was das XY Problem ist?



  • @hustbaer sagte in Check einer Konstanten auf Eindeutigkeit zur Compilezeit:

    Der Teil mit dem enum ist einfach zu beheben: gibt dem enum nen expliziten "underlying type":

    enum FunctionCode : uint8_t {
        FC_FOO = 0x11,
        FC_BAR = 0x22,
        // ...
    };
    
    void bar() {
        someFunction(static_cast<FunctionCode>(0x33));
    }
    

    Teil 1 (enum : uint8_t) ist schon so, Teil 2 mit dem static_cast funktioniert aber doch mit jeder beliebigen uint8_t-Variablen, ohne dass dabei ein gültiger Funktionscode entstehen muss?

    uint8_t irgendwas = 211;
    someFunction(static_cast<FunctionCode>(irgendwas));
    

    bringt dann was in someFunction()?

    Die oben skizzierte Variante würde durch

    someFunction(FunctionCode.code(irgendwas));
    

    immerhin alle illegalen Werte auf den Funktionscode 0 mappen.



  • @hustbaer sagte in Check einer Konstanten auf Eindeutigkeit zur Compilezeit:

    @Miq sagte in Check einer Konstanten auf Eindeutigkeit zur Compilezeit:

    @DocShoe sagte in Check einer Konstanten auf Eindeutigkeit zur Compilezeit:

    XY Problem

    Öh? Wenn ich nicht alle Details erwähnt habe, dann, um die Komplexität zu verringern, nicht, weil ich irgendwas verbergen wollte.

    Hast du nachgelesen was das XY Problem ist?

    Eigentlich ja - meint doch, ich verschleiere das eigentliche Library-Strukturproblem X, indem ich nach einer Lösung für das FunctionCode-Detail Y frage.

    Dahinter steckt natürlich, dass ich die Grundstruktur der Library nicht in Frage stellen will - sie funktioniert dafür zu gut. Ich würde eher den Support für die nicht-Standard-Codes ganz dünn oder gar weglassen, als dafür die normale Funktion zu gefährden.

    Ich experimentiere hier an und jenseits der Grenzen meines bisherigen Verständnisses von C++, deswegen kloppe ich das wieder in die Tonne, wenn es mir zu hoch, zu aufwendig oder sinnlos erscheint.

    Ich bin dennoch dankbar für Eure Beiträge, sie bringen mich immer wieder dazu, zu probieren und hinterfragen - kann ja auch unabhängig vom aktuellen Fall nur nützlich sein.



  • @Miq sagte in Check einer Konstanten auf Eindeutigkeit zur Compilezeit:

    @hustbaer sagte in Check einer Konstanten auf Eindeutigkeit zur Compilezeit:

    Der Teil mit dem enum ist einfach zu beheben: gibt dem enum nen expliziten "underlying type":

    enum FunctionCode : uint8_t {
        FC_FOO = 0x11,
        FC_BAR = 0x22,
        // ...
    };
    
    void bar() {
        someFunction(static_cast<FunctionCode>(0x33));
    }
    

    Teil 1 (enum : uint8_t) ist schon so, Teil 2 mit dem static_cast funktioniert aber doch mit jeder beliebigen uint8_t-Variablen, ohne dass dabei ein gültiger Funktionscode entstehen muss?

    uint8_t irgendwas = 211;
    someFunction(static_cast<FunctionCode>(irgendwas));
    

    bringt dann was in someFunction()?

    Naja da kommt dann 211 rein. Und das bringt das, dass die Header-Files deiner Library nicht geändert werden müssen um die 211 zu ermöglichen - trotz enum.

    Die oben skizzierte Variante würde durch

    someFunction(FunctionCode.code(irgendwas));
    

    immerhin alle illegalen Werte auf den Funktionscode 0 mappen.

    Sehe ich jetzt nicht als Vorteil.



  • @Miq sagte in Check einer Konstanten auf Eindeutigkeit zur Compilezeit:

    Hast du nachgelesen was das XY Problem ist?

    Eigentlich ja - meint doch, ich verschleiere das eigentliche Library-Strukturproblem X, indem ich nach einer Lösung für das FunctionCode-Detail Y frage.

    Der Fragende beim XY Problem will meist nix verschleiern oder geheim halten.

    Dahinter steckt natürlich, dass ich die Grundstruktur der Library nicht in Frage stellen will - sie funktioniert dafür zu gut. Ich würde eher den Support für die nicht-Standard-Codes ganz dünn oder gar weglassen, als dafür die normale Funktion zu gefährden.

    Ich will auch nicht die Grundstruktur der Library in Frage stellen. Ich wollte bloss wissen wie die aussieht. Weil man ohne das schwer konkrete Vorschläge machen kann.



  • @hustbaer Der Code steht hier. Für das Thema hier interessant sind ModbusTypeDefs.h - da steht das enum für die Funktionscodes drin - und ModbusMessage.h bzw. ModbusMessage.cpp.



  • @hustbaer sagte in Check einer Konstanten auf Eindeutigkeit zur Compilezeit

    Naja da kommt dann 211 rein. Und das bringt das, dass die Header-Files deiner Library nicht geändert werden müssen um die 211 zu ermöglichen - trotz enum.

    Die oben skizzierte Variante würde durch

    someFunction(FunctionCode.code(irgendwas));
    

    immerhin alle illegalen Werte auf den Funktionscode 0 mappen.

    Sehe ich jetzt nicht als Vorteil.

    Und in jeder dieser Funktionen muss ich dann checken, ob es ein gültiger Code ist? Nee.



  • Wieso prüfen?
    Du musst gar nix prüfen.
    Du machst einfach das was der Aufrufer vorgibt.


Anmelden zum Antworten