assert() mit Nachricht

Lesezeit: 4 Minuten

Ich habe irgendwo Assert gesehen, das mit einer Nachricht auf folgende Weise verwendet wurde:

assert(("message", condition));

Dies scheint großartig zu funktionieren, außer dass gcc die folgende Warnung ausgibt:

warning: left-hand operand of comma expression has no effect

Wie kann ich die Warnung stoppen?

  • Siehe diese verwandte Frage.

    – Razlebe

    3. Mai 2011 um 10:00 Uhr

Benutzeravatar von pmg
pmg

Verwenden -Wno-unused-value um die Warnung zu stoppen; (die Option -Wall beinhaltet -Wunused-value).

Ich denke, noch besser ist es, eine andere Methode zu verwenden, wie z

assert(condition && "message");

  • Schön, ich mache normalerweise assert(condition /* message */).

    – Julian

    22. Januar 2013 um 8:22 Uhr

  • Dadurch wird in Visual Studio manchmal die Warnung „Bedingter Ausdruck ist konstant“ ausgegeben. Irgendwelche Ideen, wie man die Warnung entfernt, ohne sie zu unterdrücken?

    – Samaura

    4. April 2013 um 23:56 Uhr

  • @Samaursa: Sie haben wahrscheinlich ein Problem mit Plain condition. Warnt der Compiler auch nur mit assert(condition);?

    – pmg

    5. April 2013 um 9:35 Uhr

  • Es tut nicht. Das Interessante ist, dass der ursprüngliche Problemcode von OP die Lösung für die Warnungen von VS ist! assert((Msg, Cond)); funktioniert ohne Warnungen auf VS 2008.

    – Samaura

    5. April 2013 um 19:58 Uhr

  • assert((<cond>) && "msg"); bewirkt, dass CppCheck (v1.90) eine „incorrectStringBooleanError“-Warnung generiert.

    – Ahogen

    4. Dezember 2019 um 22:35 Uhr

Benutzeravatar von bugfeeder
Bugfeeder

Versuchen:

#define assert__(x) for ( ; !(x) ; assert(x) )

so verwenden:

assert__(x) {
    printf("assertion will fail\n"); 
}

Führt den Block nur aus, wenn die Bestätigung fehlschlägt.

WICHTIGER HINWEIS: Diese Methode wertet den Ausdruck aus x zweimal, ggf x wertet zu false! (Das erste Mal, als die for Schleife prüft ihren Zustand; zweites Mal, wenn die assert wertet den übergebenen Ausdruck aus!)

  • Das Schöne daran ist, dass Sie die Nachricht weglassen können, wenn Sie möchten, indem Sie verwenden assert__(foo); und das Semikolon beendet den Block.

    – Kevin Cox

    10. Juni 2014 um 14:29 Uhr

  • Eine solche Implementierung wird nicht funktionieren, wenn (x) gibt nur einmal true zurück: string("a") a; assert__(a.append("b") == "ab") { ... }

    – Oleg

    27. November 2015 um 14:34 Uhr

  • Warum for und nicht if?

    – Caridorc

    3. Januar 2016 um 22:10 Uhr


  • Dies scheint in GCC nicht zu funktionieren. Versagen assert stoppt die Programmausführung und printf wird nicht gerufen.

    – VLL

    20. Mai 2021 um 12:04 Uhr

  • @vil Es ist nicht möglich für assert um das Programm vorher zu stoppen printf Weil assert wird erst danach aufgerufen printf.

    – Jack G

    22. Oktober 2021 um 22:11 Uhr

Benutzeravatar von frmdstryr
frmdstryr

Wenn Sie eine formatierte Nachricht übergeben möchten, können Sie die folgenden Makros verwenden:

#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <assert.h>

#define clean_errno() (errno == 0 ? "None" : strerror(errno))
#define log_error(M, ...) fprintf(stderr, "[ERROR] (%s:%d: errno: %s) " M "\n", __FILE__, __LINE__, clean_errno(), ##__VA_ARGS__)
#define assertf(A, M, ...) if(!(A)) {log_error(M, ##__VA_ARGS__); assert(A); }

Dann verwenden Sie es wie printf:

// With no args
assertf(self != NULL,"[Server] Failed to create server.");

// With formatting args
assertf((self->socket = u_open(self->port)) != -1,"[Server] Failed to bind to port %i:",self->port);
// etc...

Ausgabe:

[ERROR] (../src/webserver.c:180: errno: Adresse wird bereits verwendet)
[Server] Bindung an Port 8080 fehlgeschlagen: webserver: ../src/webserver.c:180: server_run: Assertion `(self->socket = u_open(self->port)) != -1′ fehlgeschlagen.

Bezogen auf http://c.learncodethehardway.org/book/ex20.html

  • Dies ist leider nicht tragbar. C99 erfordert, dass Sie mindestens eines der optionalen Argumente in einem Variadic-Makro verwenden (z. B. dieses: assertf(x == y, "x does not equal y") verstößt gegen die Norm. Dies lässt sich einfach per beheben assertf(x == y, "%s", "x does not equal y") jedoch). Es stützt sich auch auf die gcc-Erweiterung ##__VA_ARGS__ Das ist nicht unbedingt eine schlechte Sache, aber es macht es weniger tragbar

    – Tschad

    14. September 2015 um 17:49 Uhr

Aus Tradition, (void) teilt dem Compiler mit, dass Sie wissentlich einen Ausdruck ignorieren:

/* picard.c, TNG S6E11. */
#define assertmsg(x, msg) assert(((void) msg, x))
assertmsg(2+2==5, "There! are! four! lights!");

Benutzeravatar von JiaHao Xu
JiaHao Xu

Eine Funktion, die dauert const char* und kehrt zurück true würde Sie wahrscheinlich vor allerlei Warnungen bewahren:

#include <assert.h>

int always_true(const char *msg) {
    return 1;
}

#define assert_msg(expr, msg) assert((expr) && always_true(msg))

Für den unerwarteten Ausfallfall eines Schalters steht eine Option zur Verfügung

assert(!"message");

In meinem Fall habe ich die Antwort von @ pmg geändert, um die Ausgabe steuern zu können. Das (... && "message") hat bei mir nicht funktioniert.

#include <assert.h>
#include <stdio.h>

#define __DEBUG__ 1

assert ((1 == 1) && 
       (__DEBUG__ && printf("  - debug: check, ok.\n")) || !__DEBUG__);

  • Versuchen NDEBUG Anstatt von __DEBUG__. Es ist die Standardmethode, dies als Definition zu tun NDEBUG deaktiviert automatisch alle assets.

    – Jack G

    15. August um 18:13 Uhr


1410960cookie-checkassert() mit Nachricht

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy