46 Stimmen

C++ Boost: Was ist die Ursache für diese Warnung?

Ich habe ein einfaches C++ mit Boost wie dieses:

#include <boost/algorithm/string.hpp>

int main()
{
  std::string latlonStr = "hello,ergr()()rg(rg)";
  boost::find_format_all(latlonStr,boost::token_finder(boost::is_any_of("(,)")),boost::const_formatter(" "));

Dies funktioniert gut; jedes Vorkommen von ( ) wird durch ein " " ersetzt.

Beim Kompilieren erhalte ich jedoch diese Warnung:

Ich verwende MSVC 2008, Boost 1.37.0.

1>Compiling...
1>mainTest.cpp
1>c:\work\minescout-feat-000\extlib\boost\algorithm\string\detail\classification.hpp(102) : warning C4996: 'std::copy': Function call with parameters that may be unsafe - this call relies on the caller to check that the passed values are correct. To disable this warning, use -D_SCL_SECURE_NO_WARNINGS. See documentation on how to use Visual C++ 'Checked Iterators'
1>        c:\program files (x86)\microsoft visual studio 9.0\vc\include\xutility(2576) : see declaration of 'std::copy'
1>        c:\work\minescout-feat-000\extlib\boost\algorithm\string\classification.hpp(206) : see reference to function template instantiation 'boost::algorithm::detail::is_any_ofF<CharT>::is_any_ofF<boost::iterator_range<IteratorT>>(const RangeT &)' being compiled
1>        with
1>        [
1>            CharT=char,
1>            IteratorT=const char *,
1>            RangeT=boost::iterator_range<const char *>
1>        ]
1>        c:\work\minescout-feat-000\minescouttest\maintest.cpp(257) : see reference to function template instantiation 'boost::algorithm::detail::is_any_ofF<CharT> boost::algorithm::is_any_of<const char[4]>(RangeT (&))' being compiled
1>        with
1>        [
1>            CharT=char,
1>            RangeT=const char [4]
1>        ]

Ich könnte die Warnung natürlich deaktivieren, indem ich

-D_SCL_SECURE_NO_WARNINGS

aber ich zögere ein bisschen, das zu tun, bevor ich herausgefunden habe, was falsch ist, oder noch wichtiger, ob mein Code falsch ist.

52voto

jalf Punkte 235501

Das ist kein Grund zur Sorge. In den letzten Versionen von MSVC sind sie in den vollen Sicherheits-Paranoia-Modus gegangen. std::copy gibt diese Warnung aus, wenn es mit rohen Zeigern verwendet wird, weil bei unsachgemäßer Verwendung kann es zu Pufferüberläufen kommen.

Ihre Iterator-Implementierung führt eine Überprüfung der Grenzen durch, um sicherzustellen, dass dies nicht geschieht, was jedoch erhebliche Leistungseinbußen zur Folge hat.

Sie können die Warnung also gerne ignorieren. Sie bedeutet nicht, dass mit Ihrem Code etwas nicht stimmt. Sie besagt nur, dass wenn etwas mit Ihrem Code nicht stimmt, dann werden schlimme Dinge passieren. Das ist eine merkwürdige Sache, vor der man warnen sollte ;)

24 Stimmen

Diese Warnung macht mich wahnsinnig, so wie die "Warnung" vor dem heißen Inhalt einer Tasse Kaffee.

9 Stimmen

Das Schlimmste an der Sache ist, dass es keine vernünftige "Lösung" gibt. Die meisten Warnungen werden ausgegeben, weil es einen besseren, weniger fehleranfälligen Weg gibt, um das Gleiche zu erreichen. Sie können sein fest . Was sollen Sie in diesem Fall tun? Wenn Sie ein rohes C-Array haben und Daten dorthin oder daraus kopieren müssen, sind Zeiger der einzige verfügbare Typ von Iteratoren. std::copy ist bei weitem die beste und sicherste Option. Oder schlagen sie vor, dass wir wieder for-Schleifen schreiben, um dasselbe zu erreichen?

0 Stimmen

Ich wette 100 Rep, dass es im ersten SP entfernt wird, zusammen mit den anderen "Testen sie nicht, was sie veröffentlichen?

26voto

Bizmarck Punkte 2603

Sie können diese Warnung auch in bestimmten Kopfzeilen deaktivieren:

#if defined(_MSC_VER) && _MSC_VER >= 1400 
#pragma warning(push) 
#pragma warning(disable:4996) 
#endif 

/* your code */ 

#if defined(_MSC_VER) && _MSC_VER >= 1400 
#pragma warning(pop) 
#endif

9 Stimmen

Nicht notwendigerweise; zum Beispiel hat der Header <xutility>, der eine Implementierung von std::copy enthält, die als veraltet markiert ist und deren Verwendung zu dieser Warnung führt, #pragma warning(push,3) ganz oben, was den Compiler veranlasst, Ihre Warneinstellungen mit den Standardwerten der Stufe 3 zu überschreiben.

19voto

Bluebaron Punkte 1929

Wenn Sie sich sicher fühlen, diesen Fehler zu deaktivieren:

  • Gehen Sie zu den Eigenschaften Ihres C++-Projekts
  • Erweitern Sie die "C/C++"
  • Markieren Sie "Befehlszeile".
  • Fügen Sie unter "Additional Options" (Zusätzliche Optionen) den folgenden Text an den Text an, der sich in diesem Feld befinden könnte

" -D_SCL_SECURE_NO_WARNINGS"

2 Stimmen

Denken Sie daran, dass Sie, auch wenn Sie sicher sind, dass Ihr aktueller Code sicher ist, irgendwann etwas Unsicheres programmieren können, ohne dass Sie davor gewarnt werden.

2 Stimmen

Ja, aber in diesem Fall ist es so, als würde man sagen: "Nimm deinen Regenschirm mit, es könnte heute regnen". Das jeden Tag zu sagen, ist nicht sinnvoll, weil es keine Informationen liefert, nicht einmal im Sinne von Shannon. Irgendwann wird es regnen und Sie werden gewarnt worden sein, Ihren Regenschirm mitzunehmen. Wenn die Warnung lauten würde: "Die Wetterstation hat für heute eine Regenwahrscheinlichkeit von 80 % vorhergesagt, nehmen Sie Ihren Regenschirm mit", dann wäre das nützlich, weil es Informationen liefert.

6 Stimmen

Ein wenig sauberer: fügen Sie "_SCL_SECURE_NO_WARNINGS" unter Präprozessor-Definitionen hinzu (die auch unter der Kategorie "C/C++" zu finden sind)

8voto

fbrereto Punkte 34770

Die Warnung stammt von den nicht standardmäßigen "sicheren" Bibliotheksprüfungen von Visual Studio, die mit MSVC 8.0 eingeführt wurden. Microsoft hat "potenziell gefährliche" APIs identifiziert und Warnungen eingefügt, die von deren Verwendung abraten. Es ist zwar technisch möglich, std::copy auf unsichere Weise aufzurufen, aber 1) diese Warnung zu erhalten bedeutet nicht, dass Sie dies tun, und 2) die Verwendung von std::copy, wie Sie es normalerweise tun sollten, ist nicht gefährlich.

2voto

Alex Azzalini Punkte 21

Wenn Sie C++11 verwenden und die Warnungen nicht abschalten wollen, haben Sie alternativ die schmerzhafte Möglichkeit, die

boost::is_any_of(L"(,)")

mit dem folgenden Lambda-Ausdruck

[](wchar_t &c) { for (auto candidate : { L'(', L',', L')' }) { if (c == candidate) return true; }; return false; }

Möglicherweise können Sie das auch in ein Makro packen

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X