Vermisse Warnung in C++ Code

OP Moderator Persönliche Seite #7497187

Letztens hatte ich folgendes Problem, welches mir die Fehlersuche erschwerte.

Ich hatte ein Semikolon zuviel im c++-Source. Deshalb wurde ein Statement ohne Effekt erzeugt, welches aber vom g++ trotz entsprechner Compiler-Optionen unbemerkt blieb.

Hier ein runtergebrochenes Beispiel:

1
#include <string>
2
#include <iostream>
3

4
int main (void)
5
{
6
    std::string bar = "bar";
7

8
    bar = "foo bar baz:";       // <-- Dieses Semikolon ist zuviel
9
          "foo" + bar + "baz";
10

11
    std::cout << bar << std::endl;
12
}

Eigentlich war hier eine String-Concatenation über mehrere Codezeilen gewünscht, leider hat das überflüssige Semikolon das verhindert.

Trotz Übersetzung mit

1
$ g++ -O2 -Wall -Werror -Wextra -Wunused -Wpedantic a.cc && ./a.out
2
foo bar baz:

wird keine Warnung ausgegeben. Wenn ich die Zeile

1
    "foo" + bar + "baz";

auf

1
    "foo";

kürze, erscheint auch erwartungsgemäß

1
error: statement has no effect [-Werror=unused-value]

Compiler: gcc version 10.2.1 20210110 (Raspbian 10.2.1-6+rpi1)

Frage: Habe ich eine Compileroption übersehen oder hat der Compiler ein überflüssiges Statement tatsächlich übersehen?

P.S.

Der Grund, warum ich hier String-Concatenation über mehrere Zeilen benutze, wird aus dem Beispiel nicht ersichtlich. Glaubt mir, es hat einen Grund. Aber der ist hier nicht Diskussionsthema.

Persönliche Seite #7497195

Frank M. schrieb:

wird keine Warnung ausgegeben

Naja, die Konkatenation von std::string ruft den "operator +" auf, der ja durchaus auch Nebeneffekte hat (Allokation). Die kann der Compiler nicht einfach als sinnlos erkennen. Der Compiler kann nicht durchblicken, dass das Erzeugen eines neuen, konkatenierten temporären std::string und dessen anschließendes Löschen keinen wirklichen Effekt auf das Programm hat und dementsprechend warnen; im "operator +", Konstruktor, Destruktor von std::string könnte ja irgendwas wichtiges, erwünschtes passieren. Vielleicht war ja der Speicher vorher randvoll, und das Konkatenieren hätte ein OOM bewirken sollen, das könnte ja Absicht sein ;-)

Bei

1
class X {
2
  public:
3
    X foo () { return {}; }
4
};
5

6
int main () {
7
  X {}.foo ();
8
}

wird auch nicht gewarnt, obwohl es nichts tut. Und die string-Konkatenation ist noch viel komplexer (Allokation etc.).

#7497232

Moin,

Wilhelm M. schrieb:

Ab Version 13.x hat der Op+ für std::string das Attribute "nodiscard", dann bekommt man auch eine Warnung.

Zufaellig hab' ich grad' einen ofenfrischen 13.2er gcc da, das Beispiel sieht dann so aus:

1
(lfs chroot) root:~# g++ -O2 -Wall -Werror -Wextra -Wunused -Wpedantic a.cc 
2
a.cc: In function 'int main()':
3
a.cc:13:30: error: ignoring return value of 'std::__cxx11::basic_string<_CharT, _Traits, _Allocator> std::operator+(__cxx11::basic_string<_CharT, _Traits, _Allocator>&&, const _CharT*) [with _CharT = char; _Traits = char_traits<char>; _Alloc = allocator<char>]', declared with attribute 'nodiscard' [-Werror=unused-result]
4
   13 |           "foo" + bar + "baz";
5
      |                              ^
6
In file included from /usr/include/c++/13.2.0/string:54,
7
                 from a.cc:1:
8
/usr/include/c++/13.2.0/bits/basic_string.h:3676:5: note: declared here
9
 3676 |     operator+(basic_string<_CharT, _Traits, _Alloc>&& __lhs,
10
      |     ^~~~~~~~
11
cc1plus: all warnings being treated as errors

Gruss WK

#7497357

Dergute W. schrieb:

Wenn ich in meinem stillen Kaemmerlein ein LFS bau', ist ein Onlinecompiler nicht direkt das zielfuehrendste, was ich mir vorstellen kann :-)

Du kannst mit Deinem LFS machen, was Du willst.

Wenn Du allerdings verschiedene Compiler und deren Versionen auf verschiedenen Plattformen testen möchtest in Bezug auf ein MCVE eines Fragenden, so ist doch godbolt o.ä. das Mittel der Wahl.

Antwort schreiben

Eine eigene Frage? Dieser Thread ist über 3 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.