You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Using latest commit, C4996 errors and warnings spew on every string manipulation function calls:
std::strcpy (Warning)
std::strcat (Warning)
std::copy (Error - compile fail) on non-iterator/pointer destination
Error C4996 'std::copy::_Unchecked_iterators::_Deprecate': Call to 'std::copy' 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'
changing std::copy(m_start, m_end, buf.data()); to std::copy(m_start, m_end, buf.begin()); fix this problem.
warning C4996: 'strcat': This function or variable may be unsafe. Consider using strcat_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS.
I think turning off the warning like proposed on #453 before might be enough but probably not a clean solution.
Thanks for reporting! I had some headaches taking over the code with strcat/strlen, but it seemed more elegant compared to a manual search for the \0 byte. However, this manual search can be done in a for loop in this setting, so it shall be safe to replace the array<char, N> by a std::vector<char> or std::string with respective reservation of N bytes.
Since dealing with string here, In my opinion the std::string with reservation of N bytes approach is a better choice. There will be no need to call strcat/strcpy or do it manually since we got + operator and = operator. The strlen you mentioned isn't affected and still can be used, but switching to .length() is recommended.
There is only one usage of strlen on array data I found in latest commit
constauto data_end = m_buf.begin() + strlen(m_buf.data());
constbool value_is_int_like =
std::none_of(m_buf.begin(), data_end, [](constchar c)
{
return (c == '.'or c == 'e'or c == 'E');
});
which then can be switched to .cbegin(), .cend() instead.
The rationale for using std::array<char, N> instead of a std::string in this context was to avoid heap allocations, which is the performance bottleneck.
Well both std::string and std::vector does heap allocation. So for performance critical, I think ignoring the warning worth it, since we control the input data ".", "-0.0" and "0.0".
I did some refactoring to avoid the unsafe calls, see 83a9c60. I combined a call to strlen and a std::none_of to a single for loop and unrolled stdcpy/ strcat to a sequence of assignments. What do you think?
Activity
nlohmann commentedon Feb 20, 2017
Thanks for reporting! I had some headaches taking over the code with
strcat/strlen, but it seemed more elegant compared to a manual search for the\0byte. However, this manual search can be done in aforloop in this setting, so it shall be safe to replace thearray<char, N>by astd::vector<char>orstd::stringwith respective reservation ofNbytes.prsyahmi commentedon Feb 20, 2017
Since dealing with string here, In my opinion the
std::stringwith reservation ofNbytes approach is a better choice. There will be no need to callstrcat/strcpyor do it manually since we got+ operatorand= operator. Thestrlenyou mentioned isn't affected and still can be used, but switching to.length()is recommended.There is only one usage of
strlenon array data I found in latest commitwhich then can be switched to
.cbegin(),.cend()instead.TurpentineDistillery commentedon Feb 20, 2017
The rationale for using
std::array<char, N>instead of astd::stringin this context was to avoid heap allocations, which is the performance bottleneck.prsyahmi commentedon Feb 20, 2017
Well both
std::stringandstd::vectordoes heap allocation. So for performance critical, I think ignoring the warning worth it, since we control the input data ".", "-0.0" and "0.0".prsyahmi commentedon Feb 20, 2017
Another solution for the warnings
Then call like this
JSON_STRCAT(JSON_STROUT(m_buf.data(), m_buf.size()), ".0");and finally
What do you think?
🔨 refactored code to avoid using strcpy/strlen/strcat (#463)
nlohmann commentedon Feb 20, 2017
I did some refactoring to avoid the unsafe calls, see 83a9c60. I combined a call to
strlenand astd::none_ofto a singleforloop and unrolledstdcpy/strcatto a sequence of assignments. What do you think?nlohmann commentedon Feb 20, 2017
@prsyahmi Could you please try with the most recent version?
prsyahmi commentedon Feb 20, 2017
The code looks good and it compiles fine here, no more warning and error 👍 I guess this can be closed now. Thanks!