Vermisse Warnung in C++ Code

Moderator Persönliche Seite #7497187
Lesenswert?

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
Lesenswert?

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
Lesenswert?

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
Lesenswert?

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

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren