I got this warning message.. but i dont know what/where the problem is..!
includes
#pragma warning(push)
#pragma warning(disable:4996)
#include <boost/archive/iterators/base64_from_binary.hpp>
#include <boost/archive/iterators/insert_linebreaks.hpp>
#include <boost/archive/iterators/transform_width.hpp>
#include <boost/archive/iterators/ostream_iterator.hpp>
#pragma warning(pop)
and the warning
1>c:\program files (x86)\microsoft visual studio 10.0\vc\include\xutility(2227): warning C4996: 'std::_Copy_impl': 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 10.0\vc\include\xutility(2212): Siehe Deklaration von 'std::_Copy_impl'
1> c:\users\perlig\documents\visual studio 2010\projects\restmanager\restmanager\**http.cpp(257)**: Siehe Verweis auf die Instanziierung der gerade kompilierten Funktions-template "_OutIt std::copy<boost::archive::iterators::insert_linebreaks<Base,N>,boost::archive::iterators::ostream_iterator<Elem>>(_InIt,_InIt,_OutIt)".
1> with
1> [
1> _OutIt=boost::archive::iterators::ostream_iterator<char>,
1> Base=boost::archive::iterators::base64_from_binary<boost::archive::iterators::transform_width<const char *,6,8>>,
1> N=76,
1> Elem=char,
1> _InIt=boost::archive::iterators::insert_linebreaks<boost::archive::iterators::base64_from_binary<boost::archive::iterators::transform_width<const char *,6,8>>,76>
1> ]
the code occur in line 257 as the warning message says. but i´m not able to fix it because i not know what is wrong..
string data contains a "user:password" string for basic auth via http.
http.cpp(257):
// typdef, prepare
using namespace boost::archive::iterators;
stringstream os;
typedef
insert_linebreaks< // insert line breaks every 72 characters
base64_from_binary< // convert binary values ot base64 characters
transform_width< // retrieve 6 bit integers from a sequence of 8 bit bytes
const char *,
6,
8
>
>
,76
>
base64_text; // compose all the above operations in to a new iterator
// encrypt
#pragma warning(push)
#pragma warning(disable:4996)
copy( //<<<<<------ LINE 257
base64_text(data.c_str()),
base64_text(data.c_str() + data.size()),
boost::archive::iterators::ostream_iterator<char>(os)
);
#pragma warning(pop)
anybody got any idea?
I think you know what is the meaning of the warning but first I describe the warning and then say what to do to get rid of it. Microsoft implemented a new security enabled set of function in its CRT, STL, MFC, ... and mark old version of those functions as deprecated to provide a hint for you that you should migrate to new secure version. so it say std::copy is unsafe!! how? as follow:
char storage[ 10 ], *p = storage;
std::copy( std::istream_iterator<int>(std::cin), std::istream_iterator<int>(), p );
Now what will happened if user input more than 10 int? the memory will be overwritten and you corrupted your memory.
Using boost::archive::iterators::ostream_iterator is perfectly safe but since it does not follow the design of safe iterators in MSVC it will considered as unsafe.
Now you should either disable this warning by -D_SCL_SECURE_NO_WARNINGS to cl input flags or add a pragma to disable this warning( as you do ), but why pragma don't work?
the reason is obvious, this pragma work on scope and the scope that you use pragma on it have nothing wrong, you must guard xutility with this pragma and every thing will work as expected.
Related
I try to write a program check a string is Palindrone or not using vector and iterator.
I create definition in iterator.h file:-
#pragma once
#ifndef iterator
#define iterator
template<typename Bidrectional>
bool isPalindrone(Bidrectional first, Bidrectional end);
template<typename Bidrectional>
inline bool isPalindrone(Bidrectional first, Bidrectional last)
{
while (true)
{
last--;
if (first == last)
break;
if (*first != *last)
return false;
first++;
if (first == last)
{
break;
}
return true;
}
}
#endif
Now I got so many error in compile time:-
Severity Code Description Project File Line Source Suppression State
Error C4430 missing type specifier - int assumed. Note: C++ does not support default-int c++project C:\Program Files\Microsoft Visual Studio\2022\Professional\VC\Tools\MSVC\14.32.31326\include\vector 1640 Build
Error C2976 'std::reverse_iterator': too few template arguments c++project C:\Program Files\Microsoft Visual Studio\2022\Professional\VC\Tools\MSVC\14.32.31326\include\vector 656 Build
Error C4430 missing type specifier - int assumed. Note: C++ does not support default-int c++project C:\Program Files\Microsoft Visual Studio\2022\Professional\VC\Tools\MSVC\14.32.31326\include\vector 906 Build
Error C4430 missing type specifier - int assumed. Note: C++ does not support default-int c++project C:\Program Files\Microsoft Visual Studio\2022\Professional\VC\Tools\MSVC\14.32.31326\include\vector 939 Build
Error C4430 missing type specifier - int assumed. Note: C++ does not support default-int c++project C:\Program Files\Microsoft Visual Studio\2022\Professional\VC\Tools\MSVC\14.32.31326\include\vector 943 Build
Error C4430 missing type specifier - int assumed. Note: C++ does not support default-int c++project C:\Program Files\Microsoft Visual Studio\2022\Professional\VC\Tools\MSVC\14.32.31326\include\vector 947 Build
Error C4430 missing type specifier - int assumed. Note: C++ does not support default-int c++project C:\Program Files\Microsoft Visual Studio\2022\Professional\VC\Tools\MSVC\14.32.31326\include\vector 1170 Build
Error C4430 missing type specifier - int assumed. Note: C++ does not support default-int c++project C:\Program Files\Microsoft Visual Studio\2022\Professional\VC\Tools\MSVC\14.32.31326\include\vector 1186 Build
Error C4430 missing type specifier - int assumed. Note: C++ does not support default-int c++project C:\Program Files\Microsoft Visual Studio\2022\Professional\VC\Tools\MSVC\14.32.31326\include\vector 1563 Build
Error C4430 missing type specifier - int assumed. Note: C++ does not support default-int c++project C:\Program Files\Microsoft Visual Studio\2022\Professional\VC\Tools\MSVC\14.32.31326\include\vector 1583 Build
Error C2059 syntax error: '=' c++project C:\Program Files\Microsoft Visual Studio\2022\Professional\VC\Tools\MSVC\14.32.31326\include\vector 654 Build
Error C4430 missing type specifier - int assumed. Note: C++ does not support default-int c++project C:\Program Files\Microsoft Visual Studio\2022\Professional\VC\Tools\MSVC\14.32.31326\include\vector 1650 Build
Error C4430 missing type specifier - int assumed. Note: C++ does not support default-int c++project C:\Program Files\Microsoft Visual Studio\2022\Professional\VC\Tools\MSVC\14.32.31326\include\vector 2039 Build
Error C4430 missing type specifier - int assumed. Note: C++ does not support default-int c++project C:\Program Files\Microsoft Visual Studio\2022\Professional\VC\Tools\MSVC\14.32.31326\include\vector 2035 Build
Error picture:-
In main function I call is
#include <iostream>
#include "iterator.h"
#include <vector>
using namespace std;
int main()
{
vector<string> s1;
s1.push_back("Otto");
isPalindrone(s1.begin(), s1.end());
}
I am new to STL, Could you please help in this regards.
The problem is this line from the header file:
#define iterator
From that point onward, all mentions of the symbol iterator will be that macro. And it will expand to nothing.
So when e.g. std::vector defines its iterator type, it can't.
For header include guards use more complex names. Even using all upper-case (which is what most people uses for macros) would be enough.
Since your header file name is iterator.h (which is really a bad and misleading name) I suggest something like ITERATOR_H instead.
Initial Problem
You've #define iterator meaning that everywhere that the symbol iterator is used it is replaced with, well nothing but this essentially deleted the symbol iterator everywhere it's used meaning that vector and string can't find their iterator types. Try using a different name for the header guard and all capital letters is ideal by convention for macros. Also try giving the header a more complex name as iterator is too generic and could cause future errors. isPalindrone.h would be better.
Eg.
#ifndef IS_PALINDRONE_H
#define IS_PALINDRONE_H
/// ...
#endif
credit #Some programmer dude
Main Question
As for the main part of you're code, using a std::vector<std::string>>. This means that the iterator returned from s1.begin() and s1.end() are iterators to std::string types, not to the elements of the string, ie. the characters of the string. This means that, for example s1.begin() actually returns an iterator to a std::string with the value "Otto" not to a character 'O' like I assume you want.
std::vector is C++'s dynamic array type as opposed to std::string which (as the name suggests) is the most basic string type in C++.
You have two options to fix this. First std::string has iterators of its own which you can pass to you're isPalindrone() function as it stands, or you can create a std::vector<char> and push back each character. This vectors iterators will point to the elements in the vector, ie. iterators to chars. I would personally use a std::string as its easier to manage string types this way but both options work if you were to expand beyond words to say numbers maybe.
Using std::vector<char>
Here's a quick way to make a string into an array of characters.
#include <algorithm>
#include <iterator>
std::string s1 = "otto";
std::vector<char> vs(4); ///< The 4 here is used to pre-allocate memory
std::copy(s1.begin(), s1.end(), std::back_inserter(vs)) ///< Pushes the elements of s1 to the back of vs
Alternative
I know you might be trying to learn iterators and algorithm patterns in C++ but if you want an alternative to approach to achieve the same task, is you can use the std::equal algorithm (found in the <algorithm> header) and std::string's reverse iterators (the .rbegin() and .rend() methods).
#include <algorithm>
#include <string>
/// templated for different string types. Can restrict using concepts (look below)
template<typename StringT>
inline bool isPalindrone(StringT str)
{ return std::equal(str.begin(), str.end(), str.rbegin(), str.rend()); }
Quick Fix for isPalindrone()
One thing you forget to do in you're implementation of isPalindrone() is you don't decrement the end iterator each iteration. By decrementing end each loop you move backwards through the letters of the word, comparing each letter from the front forwards to the back backwards. It also should be noted that anything using templates in C++ must be in a header so the function isPalindrone() must all be in a header.
# First Loop
first
v
Otto
^ end
# Second Loop
first
v
Otto
^ end
Updated Code
template<typename Bidrectional>
inline bool isPalindrone(Bidrectional first, Bidrectional last)
{
while (true)
{
last--;
if (first == last)
break;
if (*first != *last)
return false;
first++;
end--; ///< Decrement `end`
return true;
}
}
Links and Resources
I mentioned a lot so here are links to everything I used to answer the question.
std::vector : cppreference
std::string : cppreference
Note, the link for std::string links to std::basic_string because it is used to implement all standard string types in C++. Scroll down a bit for details.
Iterators Library : cppreference
std::equal : cppreference
std::copy :cppreference
std::back_inserter : cppreference
Concepts Library (if interested) : cppreference Useful to constrain template parameters
If there is anything I missed; edits and constructive comments to help improve the answer would be appreciated.
Little modification #oraqlle solution:-
std::string s1 = "otto";
std::vector<char> vs(4); ///< The 4 here is used to pre-allocate memory
std::copy(s1.begin(), s1.end(), vs.begin());
for (auto v : vs)
{
cout << v << "\t";
}
bool a = isPalindrone(vs.begin(), vs.end());
An old method contains code like the following (anonymised):
std::wstring wstr = ...;
std::string str(wstr.begin(), wstr.end());
Previously this all compiled without warnings but as we update to C++17 and VS2019 (v142) and tidy project settings, it now gives these big scary warnings:
C:\Program Files (x86)\Microsoft Visual Studio\2019\Professional\VC\Tools\MSVC\14.28.29333\include\xstring(2468,23): warning C4244: 'argument': conversion from 'wchar_t' to 'const _Elem', possible loss of data
with
[
_Elem=char
]
C:\Program Files (x86)\Microsoft Visual Studio\2019\Professional\VC\Tools\MSVC\14.28.29333\include\xstring(2479): message : see reference to function template instantiation 'void std::basic_string<char,std::char_traits<char>,std::allocator<char>>::_Construct<wchar_t*>(_Iter,const _Iter,std::input_iterator_tag)' being compiled
with
[
_Iter=wchar_t *
]
C:\Program Files (x86)\Microsoft Visual Studio\2019\Professional\VC\Tools\MSVC\14.28.29333\include\xstring(2479): message : see reference to function template instantiation 'void std::basic_string<char,std::char_traits<char>,std::allocator<char>>::_Construct<wchar_t*>(_Iter,const _Iter,std::input_iterator_tag)' being compiled
with
[
_Iter=wchar_t *
]
C:\Program Files (x86)\Microsoft Visual Studio\2019\Professional\VC\Tools\MSVC\14.28.29333\include\xstring(2459): message : see reference to function template instantiation 'void std::basic_string<char,std::char_traits<char>,std::allocator<char>>::_Construct<wchar_t*>(const _Iter,const _Iter,std::forward_iterator_tag)' being compiled
with
[
_Iter=wchar_t *
]
C:\Program Files (x86)\Microsoft Visual Studio\2019\Professional\VC\Tools\MSVC\14.28.29333\include\xstring(2459): message : see reference to function template instantiation 'void std::basic_string<char,std::char_traits<char>,std::allocator<char>>::_Construct<wchar_t*>(const _Iter,const _Iter,std::forward_iterator_tag)' being compiled
with
[
_Iter=wchar_t *
]
message : see reference to function template instantiation 'std::basic_string<char,std::char_traits<char>,std::allocator<char>>::basic_string<std::_String_iterator<std::_String_val<std::_Simple_types<_Elem>>>,0>(_Iter,_Iter,const _Alloc &)' being compiled
with
[
_Elem=wchar_t,
_Iter=std::_String_iterator<std::_String_val<std::_Simple_types<wchar_t>>>,
_Alloc=std::allocator<char>
]
message : see reference to function template instantiation 'std::basic_string<char,std::char_traits<char>,std::allocator<char>>::basic_string<std::_String_iterator<std::_String_val<std::_Simple_types<_Elem>>>,0>(_Iter,_Iter,const _Alloc &)' being compiled
with
[
_Elem=wchar_t,
_Iter=std::_String_iterator<std::_String_val<std::_Simple_types<wchar_t>>>,
_Alloc=std::allocator<char>
]
I am pretty sure this code pre-dates use of UNICODE in our codebase - it seems to work but I don't really understand the warnings or what I should do about it.
I found this question: UTF8 to/from wide char conversion in STL but the nice neat solution has comments saying it's deprecated in C++17! It's somewhat a mystery why this code mixes string and wstring in the first place, is there an easy solution? Or is this a case "just leave it if it works?!"
The issue is that you are converting from a 16 bit string to an 8 bit string. Since 16 bits hold more data than 8, data will then get lost. If you are converting between UTF-16 and UTF-8, you need to do it properly with a conversion library.
C++ does provide conversion library in the form of: codecvt (Deprecated in C++17 but still there for a while).
If you are sure the string only contains ASCII, you can suppress the warning.
See https://en.cppreference.com/w/cpp/locale/codecvt_utf8_utf16 for details
The warning is quite clear on its own.
warning C4244: 'argument': conversion from 'wchar_t' to 'const _Elem',
possible loss of data
Which means, this line std::string str(wstr.begin(), wstr.end()) involves a type casting from wchar_t to a narrower data type const _Elem a.k.a char. Since any narrowing cast may lead to data loss, hence the warning.
Consider an example as following:
#include <cstddef>
#include <iostream>
#include <string>
int main() {
std::wstring ws{};
auto c = (wchar_t)0x41'42'43'44; // A'B'C'D in ASCII
for (int i = 0; i < 3; ++i)
ws.push_back(c);
std::string str{ws.begin(), ws.end()};
std::cout << str.c_str() << std::endl;
}
The code above run and print DDD.
On 64 bit machine, the constructor of str move 4 bytes at a time to read a wchar_t. However, string type can only accept element as char ==> the constructor must perform a narrowing cast from wchar_t to char which results in a loss of 3 byte A B C for each wchar_t element.
I have the following lines in a rather large file:
#include <sha.h>
#include <hex.h>
Which, when compiled, throws this compiler error:
1>d:\work\app\tools\cryptopp\algparam.h(322): error C2061: syntax error : identifier 'buffer'
1> d:\work\app\tools\cryptopp\algparam.h(321) : while compiling class template member function 'void CryptoPP::AlgorithmParametersTemplate<T>::MoveInto(void *) const'
1> with
1> [
1> T=bool
1> ]
1> d:\work\app\tools\cryptopp\algparam.h(329) : see reference to class template instantiation 'CryptoPP::AlgorithmParametersTemplate<T>' being compiled
1> with
1> [
1> T=bool
1> ]
I'm pretty sure I'm forgetting something, but I'm not sure what. If I don't include hex.h, I don't have any problems and I get a SHA256 hash just fine, but when I do include hex.h, the error pops up.
Edit
In case anyone wonders, from algparam.h of Crypto++ toolkit:
void MoveInto(void *buffer) const //<=== line 320
{
AlgorithmParametersTemplate<T>* p = new(buffer)
AlgorithmParametersTemplate<T>(*this);
}
CRYPTOPP_DLL_TEMPLATE_CLASS AlgorithmParametersTemplate<bool>; // <== line 329
Edit: Removed unrelated code
I fixed the problem by temporarily undefining new, which was defined as a macro to some extra debugging code.
#pragma push_macro("new")
#undef new
/* #includes for Crypto++ go here */
#pragma pop_macro("new")
If you're including Crypto++ in a Visual Studio project with MFC support, this error might be caused by this line:
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
Make sure to remove it or comment it out.
I'm using the Visual Studio 11 beta and I'm curious about a compilation error i'm getting storing a std::function object in my class.
typedef std::function<void (int, const char*, int, int, const char*)> MyCallback;
In my class I have,
MyCallback m_callback;
This compiles just fine. If I add one more argument to the list it fails.
typedef std::function<void (int, const char*, int, int, const char*, int)> MyCallback;
The failure is:
>c:\program files (x86)\microsoft visual studio 11.0\vc\include\functional(535): error C2027: use of undefined type 'std::_Get_function_impl<_Tx>'
1> with
1> [
1> _Tx=void (int,const char *,int,int,const char *,int)
1> ]
1> f:\development\projects\applications\my.h(72) : see reference to class template instantiation 'std::function<_Fty>' being compiled
1> with
1> [
1> _Fty=void (int,const char *,int,int,const char *,int)
1> ]
1>c:\program files (x86)\microsoft visual studio 11.0\vc\include\functional(536): error C2504: 'type' : base class undefined
1>c:\program files (x86)\microsoft visual studio 11.0\vc\include\functional(539): error C2027: use of undefined type 'std::_Get_function_impl<_Tx>'
1> with
1> [
1> _Tx=void (int,const char *,int,int,const char *,int)
1> ]
1>c:\program files (x86)\microsoft visual studio 11.0\vc\include\functional(539): error C2146: syntax error : missing ';' before identifier '_Mybase'
1>c:\program files (x86)\microsoft visual studio 11.0\vc\include\functional(539): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
This is a dynamically linked library which is preparing data to pass to another application. I can certainly rework the format of the data so that it can be passed with fewer arguments, but I was wondering why I see this limit?
Switching back to the c-style function pointer,
typedef void (*MyCallback)(int, const char*, int, int, const char*, int);
seems to work fine.
This limit is set by the implementation in Visual Studio.
The C++ specification for std::function does not place any limit. std::function uses variadic templates to work with any number of arguments. Implementations may have a limit based on, e.g., template instantiation nesting limits, but it should be large. The spec suggests 1024 as a good minimum supported nesting depth, and 256 as a good minimum for arguments allowed in one function call, for example.
Visual Studio (as of VS11) does not have variadic templates. They simulate them up to 5 arguments in VS11, though you can change it to up to 10. Do this by defining _VARIADIC_MAX in your project. This can increase compile times greatly.
Update: The VS 2012 Nov CTP adds support for variadic templates, but the standard library has not yet been updated to use them. Once it is updated you should be able to use as many arguments as you want with std::function.
Got some code that is not mine and its producing this warning atm:
iehtmlwin.cpp(264) : warning C4996: 'std::basic_string<_Elem,_Traits,_Ax>::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'
with
[
_Elem=char,
_Traits=std::char_traits<char>,
_Ax=std::allocator<char>
]
c:\program files (x86)\microsoft visual studio 8\vc\include\xstring(1680) : see declaration of 'std::basic_string<_Elem,_Traits,_Ax>::copy'
with
[
_Elem=char,
_Traits=std::char_traits<char>,
_Ax=std::allocator<char>
]
this is the code in question:
HRESULT STDMETHODCALLTYPE Read(void __RPC_FAR *pv, ULONG cb, ULONG __RPC_FAR *pcbRead)
{
if (prepend.size() > 0)
{
int n = min(prepend.size(), cb);
prepend.copy((char *) pv, n);
prepend = prepend.substr(n);
if (pcbRead)
*pcbRead = n;
return S_OK;
};
int rc = Read((char *) pv, cb);
if (pcbRead)
*pcbRead = rc;
return S_OK;
};
and the warning refers to the prepend.copy line. I have tried googling the warning but cant work out what it is on about. Can some one help me solve this please.
Visual Studio 2005 SP1
Windows 7 RC1
.
Edit: prepend is a string which is typedefed
typedef basic_string<char, char_traits<char>, allocator<char> > string;
The warning is telling you that you risk a buffer overflow if n is too large -- which you know can't happen because of the way you just computed with a min, but the poor commpiler doesn't. I suggest you take the compiler's own advice and use -D_SCL_SECURE_NO_WARNINGS for this one source file...
Check out this MSDN page for documentation on the warning
http://msdn.microsoft.com/en-us/library/ttcz0bys.aspx
The MS C++ compiler decided to deprecate the method std::string::copy because it is potentially unsafe to use and can lead to a buffer overrun. This deprecation is Microsoft specific and you will likely not see it on other compiler platforms.