Frage

Gibt es eine Möglichkeit, die C / C ++ Präprozessor oder eine Vorlage zu erhalten oder solche / hash den __FILE__ und __LINE__ und vielleicht einig anderen externen Eingang wie eine Build-Nummer in eine einzige Kurznummer mangle, die in Protokollen zitiert werden können, oder Fehlermeldungen?

(Die Absicht wäre in der Lage sein, um es rückgängig zu machen (auf eine Liste von Kandidaten, wenn seine verlustbehafteten) bei Bedarf, wenn ein Kunde in einem Fehlerbericht zitiert.)

War es hilfreich?

Lösung

Sie müssen eine Funktion verwenden, um das Hashing auszuführen und einen Code aus __LINE__ und __FILE__ zu erstellen, wie der C-Präprozessor nicht in der Lage ist, solche komplexen Aufgaben zu tun.

Wie auch immer, können Sie Inspiration von diesem Artikel rel="nofollow ein, um zu sehen, ob andere Lösung besser sein kann, auf Ihre Situation.

Andere Tipps

Nun ... Sie so etwas wie verwenden:

((*(int*)__FILE__ && 0xFFFF0000) | version << 8 | __LINE__ )

Es wäre nicht vollkommen eindeutig sein, aber es könnte für Arbeit, was Sie wollen. Könnte diese OPs bis + ändern, was für einige Dinge besser funktionieren könnte.

Natürlich, wenn Sie tatsächlich einen Hash-Code erstellen können, werden Sie wahrscheinlich das tun wollen.

Ich brauchte serielle valuse in einem Projekt von mir und bekam sie durch eine Vorlage zu machen, die auf __LINE__ und __FILE__ spezialisiert und führten auch in einem int als Erzeugung (wie die Kompilierung auf stdout ausgegeben) eine Template-Spezialisierung für seine Eingaben, die in Folge in der Zeile Nummer dieser Vorlage. Diese wurden zum ersten Mal durch den Compiler gesammelt und dann abgeladen in eine Code-Datei und das Programm wurde wieder zusammengestellt. Diese Zeit jeder Standort, der die Vorlage verwendet wurde bekam eine andere Zahl.

(in D getan, damit es nicht möglich sein könnte, in C ++)

template Serial(char[] file, int line)
{
    prgams(msg, 
    "template Serial(char[] file : \"~file~"\", int line : "~line.stringof~")"
      "{const int Serial = __LINE__;");
    const int Serial = -1;
}

Eine einfachere Lösung wäre eine globale statische „Fehlerstelle“ Variable zu halten.

#ifdef DEBUG
#define trace_here(version) printf("[%d]%s:%d {%d}\n", version, __FILE__, __LINE__, errloc++);
#else
#define trace_here(version) printf("{%lu}\n", version<<16|errloc++);
#endif

oder ohne printf .. erhöhen einfach die errloc jedes Mal wenn Sie eine Tracepoint überqueren. Dann können Sie den Wert auf der Linie / Anzahl / Version korrelieren die in Ihrem Debug ausspucken Builds ziemlich leicht.

Sie müßten auf Version enthalten oder Build-Nummer, da diese Fehlerstellen mit jedem Build ändern könnten.

Ist auch nicht, wenn Sie die Codepfade nicht wiedergeben kann.

__ FILE__ ist ein Zeiger in den Konstanten Bereich des Programms. Wenn Sie die Ausgabe der Unterschied zwischen diesem und einem anderen konstanten sollten Sie ein Ergebnis bekommen, dass jeder Umzug unabhängig ist, etc:

extern const char g_DebugAnchor;
#define FILE_STR_OFFSET (__FILE__ - &g_DebugAnchor)

Sie können dann darüber berichten, oder es in irgendeiner Weise mit der Zeilennummer verbinden usw. Die mittleren Bits von FILE_STR_OFFSET sind wahrscheinlich die interessanteste.

Nun, wenn Sie die Nachricht an den Benutzer sind die Anzeige selbst (im Gegensatz zu einem Absturz Adresse oder Funktion vom System angezeigt werden, um mit), gibt es nichts zu halten Sie von der Anzeige genau das, was Sie wollen.

Zum Beispiel:

typedef union ErrorCode {
    struct {
        unsigned int file: 15;
        unsigned int line: 12; /* Better than 5 bits, still not great
                                  Thanks commenters!! */
        unsigned int build: 5;
    } bits;
    unsigned int code;
} ErrorCode;

unsigned int buildErrorCodes(const char *file, int line, int build)
{
    ErrorCode code;
    code.bits.line=line   & ((1<<12) - 1);
    code.bits.build=build & ((1<< 5) - 1);
    code.bits.file=some_hash_function(file) & ((1<<15) - 1);

    return code.code;
}

Sie würden verwenden, die als

buildErrorCodes(__FILE__, __LINE__, BUILD_CODE) 

und Ausgabe, die es in hex. Es wäre nicht sehr schwer zu entschlüsseln ...

(Edited -. Die commen sind richtig, ich muss verrückt gewesen 5 Bits für die Zeilennummer angeben Modulo 4096 jedoch Zeilen mit Fehlermeldungen sind nicht geeignet, kollidieren 5 Bits für Build ist noch in Ordnung. - 32 Modulo bedeutet, dass nur 32 baut kann hervorragend sein und der Fehler immer noch auf der gleichen Linie passieren.)

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top