“Verwendung eines vorzeichenbehafteten Integer-Operanden mit einem binären bitweisen Operator” – bei Verwendung von unsigned short

Lesezeit: 5 Minuten

Im folgenden C-Schnipsel, der prüft, ob die ersten beiden Bits einer 16-Bit-Sequenz gesetzt sind:

bool is_pointer(unsigned short int sequence) {
  return (sequence >> 14) == 3;
}

Clang-Tidy von CLion gibt mir eine Warnung “Verwendung eines vorzeichenbehafteten Ganzzahloperanden mit einem binären bitweisen Operator”, und ich kann nicht verstehen, warum. Ist unsigned short nicht unsigniert genug?

  • Klingt nach einem Fehler.

    – Oliver Charlesworth

    17. Mai 2018 um 19:26 Uhr

  • Es wird in JetBrains CLion behoben. Es gibt eine Diskussion von 2018 in Clang-Tidy-Bug 36961ist aber noch nicht behoben.

    – Roland Illig

    8. Oktober 2019 um 16:04 Uhr


  • Ich habe den Perforce-Support kontaktiert und um eine Klärung dieses Problems gebeten. Mal sehen, was sie antworten. (Perforce ist der Betreuer des Standards, der von clang-tidy implementiert wird und wiederum in CLion verwendet wird.)

    – Roland Illig

    12. Dezember 2019 um 23:37 Uhr


Benutzeravatar von Ryan Haining
Ryan Haining

Der Code für diese Warnung überprüft ob entweder Operand des bitweisen Operators ist signiert. Es ist nicht sequence verursacht die Warnung, aber 14und Sie können das Problem lindern, indem Sie machen 14 unsigniert durch Anhängen von a u bis zum Ende.

(sequence >> 14u)

Diese Warnung ist schlecht. Wie Rolands Antwort beschreibt, behebt CLion dies.

  • Wow … einfach wow … Ich frage mich, warum es sich nicht darüber beschwert sequence das wird zu a befördert signed int.

    – Antti Haapala – Слава Україні

    17. Mai 2018 um 19:50 Uhr


  • @AnttiHaapala, es ist ein ziemlich seltsamer Scheck, da stimme ich zu

    – Ryan Haining

    17. Mai 2018 um 21:03 Uhr

  • Ich habe diese Antwort akzeptiert, weil dadurch die Warnung verschwunden ist, während die andere dies nicht getan hat 🙂

    – SakoDaemon

    17. Mai 2018 um 21:26 Uhr

  • Es ist nicht immer gut, eine „Warnung verschwinden“ zu lassen. In einigen Fällen (wie diesem) ist die Warnung falsch, nicht Ihr Code. Vertrauen Sie den Warnungen nicht blind. Versuchen Sie stattdessen, sie zu verstehen, und entscheiden Sie dann, wer falsch liegt.

    – Roland Illig

    6. Februar 2020 um 17:09 Uhr

Benutzeravatar von Roland Illig
Roland Illig

Es gibt einen Check in Clang-Ordnung, der aufgerufen wird hicpp-signed-bitwise. Diese Prüfung folgt dem Wortlaut des HIC++-Standards. Diese Norm ist frei verfügbar und sagt:

5.6.1. Verwenden Sie keine bitweisen Operatoren mit vorzeichenbehafteten Operanden

Die Verwendung von vorzeichenbehafteten Operanden mit bitweisen Operatoren unterliegt in einigen Fällen einem undefinierten oder implementierungsdefinierten Verhalten. Daher sollten bitweise Operatoren nur mit Operanden ganzzahliger Typen ohne Vorzeichen verwendet werden.

Die Autoren des HIC++-Codierungsstandards haben die Absicht der C- und C++-Standards falsch interpretiert und sich entweder versehentlich oder absichtlich auf die konzentriert Typ der Operanden statt der Wert der Operanden.

Der Check in clang-tidy setzt genau diese Formulierung um, um diesem Standard zu entsprechen. Dieser Scheck ist nicht als allgemein nützlich gedachtsein einziger Zweck ist es, den armen Seelen zu helfen, deren Programme dieser einen dummen Regel des HIC++-Standards entsprechen müssen.

Der entscheidende Punkt ist, dass ganzzahlige Literale ohne Suffix per Definition vom Typ sind int, und dieser Typ ist als signierter Typ definiert. HIC++ kommt nun fälschlicherweise zu dem Schluss, dass positive Integer-Literale negativ sein könnten und somit könnten Rufen Sie undefiniertes Verhalten auf.

Zum Vergleich sagt der C11-Standard:

6.5.7 Bitweise Verschiebungsoperatoren

Wenn der Wert des rechten Operanden negativ oder größer oder gleich der Breite des heraufgestuften linken Operanden ist, ist das Verhalten nicht definiert.

Diese Formulierung ist sorgfältig gewählt und betont, dass die Wert des rechten Operanden ist wichtig, nicht sein Typ. Es deckt auch den Fall eines zu großen Werts ab, während der HIC++-Standard diesen Fall einfach vergisst. Deshalb sagen 1u << 1000u ist in HIC++ ok, während 1 << 3 ist nicht.

Die beste Strategie besteht darin, diese einzelne Prüfung explizit zu deaktivieren. Es gibt mehrere Fehlerberichte für CLion Erwähne dies, und es wird dort behoben.


Update 16.12.2019: Ich habe Perforce gefragt, was die Motivation hinter dieser genauen Formulierung war und ob die Formulierung Absicht war. Hier ist ihre Antwort:

Unser C++-Team, das an der Erstellung des HIC++-Standards beteiligt war, hat sich die von Ihnen erwähnte Stack Overflow-Frage angesehen.

Kurz gesagt, der Verweis auf den Objekttyp in der HIC++-Regel anstelle des Werts ist eine bewusste Wahl, um eine einfachere automatische Überprüfung des Codes zu ermöglichen. Der Typ eines Objekts ist immer bekannt, der Wert jedoch nicht.

  • HIC++-Regeln zielen im Allgemeinen darauf ab, “entscheidbar” zu sein. Das Erzwingen gegen den Typ stellt sicher, dass eine entscheidbare Prüfung immer möglich ist, dh. direkt dort, wo der Operator verwendet wird oder wo ein vorzeichenbehafteter Typ in einen vorzeichenlosen umgewandelt wird.
  • Die Begründung bezieht sich ausdrücklich auf “mögliches” undefiniertes Verhalten, daher kann eine sinnvolle Umsetzung ausschließen:
    • Konstanten, es sei denn, es gibt definitiv ein Problem und
    • unsignierte Typen, die zu signierten Typen heraufgestuft werden.
  • Daher ist es am besten, wenn CLion die Überprüfung vor der Heraufstufung auf nicht konstante Typen beschränkt.

  • Das potenzielle Problem besteht darin, dass negative Werte nach rechts verschoben werden. Stellt die CPU eine 0 (vorher war nichts da) oder eine 1 (Beibehaltung der Negativität) voran?

    – Lungenentzündung

    28. Juni 2020 um 8:40 Uhr

  • @Pnemonic Ja, das ist ein weiterer Bereich mit undefiniertem Verhalten. Aber das hat nichts mit diesem HICPP-Check zu tun, bei dem es um die Verwechslung von Haben geht Typen, die negative Werte zulassen und Werte haben, die negativ sein können.

    – Roland Illig

    29. Juni 2020 um 18:19 Uhr

  • Um die Regel in CLion zu deaktivieren, gehen Sie zu Datei > Einstellungen/Präferenzen > Editor > Inspektionen und wählen Sie im rechten Bereich Clang-Tidy aus. Schreiben Sie unter Optionen in das Feld „Komma-getrennte Liste aktivierter und deaktivierter Prüfungen“ ein Komma und dann -hicpp-signed-bitwiseund drücken Sie OK.

    – Mikrofon

    10. November 2020 um 16:59 Uhr

  • @mic Danke für die Problemumgehung. Das ist aber keine richtige Lösung. Wenn ich die Regel in meiner persönlichen Kopie der IDE deaktiviere, verhindert dies nicht, dass andere ebenfalls verwirrt werden. Daher ist das einzig Vernünftige, den Distributor dieser falschen Überprüfung (in diesem Fall JetBrains und weiter vorgeschaltet Clang-Tidy) zu informieren, um dies zu beheben.

    – Roland Illig

    14. November 2020 um 12:07 Uhr

Ich denke, die Integer-Promotion verursacht hier die Warnung. Operanden kleiner als int werden für den vorzeichenbehafteten arithmetischen Ausdruck zu einer ganzen Zahl erweitert. Ihr Code ist also effektiv return ( (int)sequence >> 14)==3; was zu der Warnung führt. Versuchen return ( (unsigned)sequence >> 14)==3; oder return (sequence & 0xC000)==0xC000;.

  • Als ich diese Frage las, war dies auch mein Gedanke … aber dann tauchte die (derzeit akzeptierte) andere Antwort auf, bevor ich meine eigene Antwort einreichte, was mich zu der Annahme veranlasst, dass Oliver Recht hatte … C11/6.3.1.1p2 ist dein Zitat, btw

    – autistisch

    17. Mai 2018 um 20:33 Uhr

1414940cookie-check“Verwendung eines vorzeichenbehafteten Integer-Operanden mit einem binären bitweisen Operator” – bei Verwendung von unsigned short

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

Privacy policy