For Programmers: Free Programming Magazines  


Home > Archive > VC STL > March 2006 > Anyone know how to use the "Safe Standard C++ Library"?









You are viewing an archived Text-only version of the thread. To view this thread in it's original format and/or if you want to reply to this thread please [click here]

 

Author Anyone know how to use the "Safe Standard C++ Library"?
Arnie

2006-02-02, 7:10 pm

VC++ 8.0

The following code produces the following warning. The 'copy'
function isn't declared deprecated in the doc. Does nayone know
the 'proper' way to use it?

Thanks,
- Arnie

set<int> setFilter;

copy(setFilter.begin(), setFilter.end(), filter.sx2bin);

1>c:\program files\microsoft visual studio
8\vc\include\xutility(2282) : warning C4996: 'std::_Copy_opt' was
declared deprecated

1> c:\program files\microsoft visual studio
8\vc\include\xutility(2270) : see declaration of 'std::_Copy_opt'

1> Message: 'You have used a std:: construct that is not safe.
See documentation on how to use the Safe Standard C++ Library'

1> c:\mxxr\vcdevelopment\ba\bcmpsum\bcmpsum
.cpp(572) : see
reference to function template instantiation '_OutIt
std::copy<std::_Tree<_Traits>::iterator,int*>(_InIt,_InIt,_OutIt)'
being compiled

1> with

1> [

1> _OutIt=int *,

1>
_Traits=std::_Tset_traits<int,std::less<int>,std::allocator<int>,false>,

1>
_InIt=std::_Tree<std::_Tset_traits<int,std::less<int>,std::allocator<int>,false>>::iterator

1> ]




Igor Tandetnik

2006-02-02, 7:10 pm

Arnie <none> wrote:
> VC++ 8.0
>
> The following code produces the following warning. The 'copy'
> function isn't declared deprecated in the doc. Does nayone know
> the 'proper' way to use it?
>
> Thanks,
> - Arnie
>
> set<int> setFilter;
>
> copy(setFilter.begin(), setFilter.end(), filter.sx2bin);


[warnings skipped]

Essentially, the compiler is trying to warn you that this call is unsafe
and can lead to buffer overruns (well, in this case the program can end
up reading past the end of the buffer rather than writing, so it's not
that bad). The last parameter is a raw pointer, there is no way to know
how large the buffer is, so there is a risk of copying more data than is
available.

The recommended solution is as follows:

copy(setFilter.begin(), setFilter.end(),
stdext::checked_array_iterator(filter.sx2bin, bufferSize) );

If the call does end up reading past the end of the buffer, the debug
build will throw an exception at runtime.

Or, you can define _SECURE_SCL macro to 0 and return to the old
(unchecked, insecure) behavior.
--
With best wishes,
Igor Tandetnik

With sufficient thrust, pigs fly just fine. However, this is not
necessarily a good idea. It is hard to be sure where they are going to
land, and it could be dangerous sitting under them as they fly
overhead. -- RFC 1925


Arnie

2006-02-02, 7:10 pm

>> set<int> setFilter;
>
> Essentially, the compiler is trying to warn you that this call
> is unsafe and can lead to buffer overruns (well, in this case
> the program can end up reading past the end of the buffer
> rather than writing, so it's not that bad). The last parameter
> is a raw pointer, there is no way to know how large the buffer
> is, so there is a risk of copying more data than is available.
>
> The recommended solution is as follows:
>
> copy(setFilter.begin(), setFilter.end(),
> stdext::checked_array_iterator(filter.sx2bin, bufferSize) );
>
> If the call does end up reading past the end of the buffer, the
> debug build will throw an exception at runtime.
>
> Or, you can define _SECURE_SCL macro to 0 and return to the old
> (unchecked, insecure) behavior.
> --
> With best wishes,
> Igor Tandetnik


Thanks for the info and your prompt reply.

filter is a struct and sx2bin is an int *. There's no way to
know its size at this point in the code, though it's known to
always be large enough for the copy (I have a bridge ...).
Unfortunately, it's used all over the place. Perhaps one day we
can turn it into a vector<int>.

Thanks again,
- Arnie


Pete Becker

2006-02-02, 7:10 pm

Arnie wrote:
>
> Thanks for the info and your prompt reply.
>
> filter is a struct and sx2bin is an int *. There's no way to
> know its size at this point in the code, though it's known to
> always be large enough for the copy (I have a bridge ...).


Well, another way to write that code would be

copy(setFilter.begin(), setFilter.end(),
stdext::checked_array_iterator(filter.sx2bin,
distance(setFilter.begin(), setFilter.end()));

Thus rendering that "safe" call no longer "safe," and maybe
significantly slower, to boot. But at least the warning will go away.

--

Pete Becker

Igor Tandetnik

2006-02-02, 7:10 pm

Igor Tandetnik <itandetnik@mvps.org> wrote:
> Arnie <none> wrote:
>
> [warnings skipped]
>
> Essentially, the compiler is trying to warn you that this call is
> unsafe and can lead to buffer overruns (well, in this case the
> program can end up reading past the end of the buffer rather than
> writing, so it's not that bad).


The comment in parentheses is obviously wrong - sorry for that. Of
course copy() writes to the buffer pointed to by the last parameter, so
you can get the usual buffer overrun.
--
With best wishes,
Igor Tandetnik

With sufficient thrust, pigs fly just fine. However, this is not
necessarily a good idea. It is hard to be sure where they are going to
land, and it could be dangerous sitting under them as they fly
overhead. -- RFC 1925


Igor Tandetnik

2006-02-02, 7:10 pm

Pete Becker <petebecker@acm.org> wrote:
> Arnie wrote:
>
> Well, another way to write that code would be
>
> copy(setFilter.begin(), setFilter.end(),
> stdext::checked_array_iterator(filter.sx2bin,
> distance(setFilter.begin(), setFilter.end()));
>
> Thus rendering that "safe" call no longer "safe," and maybe
> significantly slower, to boot. But at least the warning will go away.


Or, you can use stdext::unchecked_copy, which behaves just like the
copy() of old (no checks regardless of how _SECURE_SCL is defined).
--
With best wishes,
Igor Tandetnik

With sufficient thrust, pigs fly just fine. However, this is not
necessarily a good idea. It is hard to be sure where they are going to
land, and it could be dangerous sitting under them as they fly
overhead. -- RFC 1925


Pete Becker

2006-02-02, 7:10 pm

Igor Tandetnik wrote:

> Pete Becker <petebecker@acm.org> wrote:
>
>
>
> Or, you can use stdext::unchecked_copy, which behaves just like the
> copy() of old (no checks regardless of how _SECURE_SCL is defined).


Warnings about valid, portable, meaningful code are frustrating enough.
Usually there's a workaround through some other way of writing the same
expression that's also valid, portable, and almost as meaningful. This
workaround is not portable. I'll shut that warning off, thank you.

--

Pete Becker
Dinkumware, Ltd. (http://www.dinkumware.com)
Igor Tandetnik

2006-02-02, 9:59 pm

"Pete Becker" <petebecker@acm.org> wrote in message
news:0M2dnfLNtoRBMX_eRVn-qw@giganews.com
> Igor Tandetnik wrote:
>
>
> Warnings about valid, portable, meaningful code are frustrating
> enough. Usually there's a workaround through some other way of
> writing the same expression that's also valid, portable, and almost
> as meaningful. This workaround is not portable. I'll shut that
> warning off, thank you.


How is your suggestion using stdext::checked_array_iterator more
portable, or in any other way better?
--
With best wishes,
Igor Tandetnik

With sufficient thrust, pigs fly just fine. However, this is not
necessarily a good idea. It is hard to be sure where they are going to
land, and it could be dangerous sitting under them as they fly
overhead. -- RFC 1925


Tom Widmer [VC++ MVP]

2006-02-08, 10:12 am

Pete Becker wrote:

>
>
> Warnings about valid, portable, meaningful code are frustrating enough.
> Usually there's a workaround through some other way of writing the same
> expression that's also valid, portable, and almost as meaningful. This
> workaround is not portable. I'll shut that warning off, thank you.


It's a wonderful example of vendor lock-in - take completely standard
and portable code, then make your compiler output spurious warnings
about correct usages (using the word "deprecated", implying that the
code is deprecated by the C++ standard), and finally recommend that they
use your non-portable, non-standard alternative.

It takes a special kind of mind to come up with that, I think, whether
the intention was honorable or not.

Tom
Pete Becker

2006-02-08, 10:12 am

Igor Tandetnik wrote:
> "Pete Becker" <petebecker@acm.org> wrote in message
> news:0M2dnfLNtoRBMX_eRVn-qw@giganews.com
>
>
>
> How is your suggestion using stdext::checked_array_iterator more
> portable, or in any other way better?


It's not. It was facetious.

--

Pete Becker
Dinkumware, Ltd. (http://www.dinkumware.com)
devnull@octopull.demon.co.uk

2006-02-08, 10:12 am

Arnie wrote:

> VC++ 8.0
>
> The following code produces the following warning. The 'copy'
> function isn't declared deprecated in the doc. Does nayone know
> the 'proper' way to use it?


Yes. Disable the warning (-D_SCL_SECURE_NO_DEPRECATE).

For the rationale:


http://www.octopull.demon.co.uk/edi...orial200511.pdf
--
Alan Griffiths

Stephen Howe

2006-02-08, 10:12 am

> Tom

Perhaps as a suggestion Microsoft adds a warnning category level of 5 and
moves all the non-standard deprecrated messages to this category.
Programmers would never see them if the warning level is compiled at 4.

Stephen Howe




Carl Daniel [VC++ MVP]

2006-02-08, 10:12 am

Stephen Howe wrote:
>
> Perhaps as a suggestion Microsoft adds a warnning category level of 5
> and moves all the non-standard deprecrated messages to this category.
> Programmers would never see them if the warning level is compiled at
> 4.


Tell the VC++ devs directly:

http://lab.msdn.microsoft.com/productfeedback.

-cd


Jeff F

2006-02-08, 10:12 am

Carl Daniel [VC++ MVP] wrote:
> Stephen Howe wrote:
>
> Tell the VC++ devs directly:
>
> http://lab.msdn.microsoft.com/productfeedback.


Just did:

Bug ID: FDBK45491


Jeff


Stephen Howe

2006-02-08, 7:08 pm

> Bug ID: FDBK45491

Thanks Jeff.

The point I did not mention is that any company that takes Microsofts
deprecation warnings seriously (but they should not use the word
"deprecate") could always make it mandatory that level 5 is used and no
warrnings would be tolerated.

For the rest of us - we just don't bother.

The only downside to what I suggested is a marketing one.
It send the message that security conscious code is at level 5 - below other
warning levels.

Stephen Howe



yinyang

2006-03-01, 7:59 am

Hi

> filter is a struct and sx2bin is an int *. There's no way to know its
> size at this point in the code, though it's known to always be large
> enough for the copy (I have a bridge ...).


don't now if it helps, but I use simple pointer extension to following
structure (or class)

class Cint_ptr
{
private:
int* ptr;
size_t size;

public:
Cint_ptr(int arr_size):
size(arr_size)
{
ptr = new int[size];
};

~Cint_ptr()
{
delete [] ptr;
};

int * getptr()
{
return ptr;
};

size_t getsize()
{
return size;
};
}

of course you can extend to templates blabla and so on but by storing such
class instance you can retain array size.

Pro's:
-knowledge about size of array pointer points to; (this is clue of my reply)
-significantly faster than std::vector<int>. (this is most times what I need
for instance)

Con's:
-cannot add or remove elements randomly (no simple memory block resizing
possible).
-generally none of std::vector functionalities :-(

Greetings
marcin

Jason Winnebeck

2006-03-01, 7:03 pm

yinyang wrote:

> Pro's:
> -knowledge about size of array pointer points to; (this is clue of my
> reply)
> -significantly faster than std::vector<int>. (this is most times what I
> need for instance)


I would quite possibly debate you on that. If all you are using is
operator [], then vector should be as fast as your class. I know from
my tests in VC 7.1, vectors and arrays have the same speed if you don't
do things with the vectors that you can't do with the arrays (like
dynamic resizing).

Jason
Tom Widmer [VC++ MVP]

2006-03-02, 7:58 am

Jason Winnebeck wrote:
> yinyang wrote:
>
>
>
> I would quite possibly debate you on that. If all you are using is
> operator [], then vector should be as fast as your class. I know from
> my tests in VC 7.1, vectors and arrays have the same speed if you don't
> do things with the vectors that you can't do with the arrays (like
> dynamic resizing).


The obvious loss for std::vector is that it must copy initialize every
element - sometimes you only need an uninitialized buffer, since it's
going to be overwritten anyway. e.g.

int* buffer = new int[1000000];
std::vector<int> buffer(1000000);

The latter must actually 0 all those ints.

However, I think it would be hard to find an application in which that
caused a noticeable difference to overall performance...

Tom
Jason Winnebeck

2006-03-02, 7:04 pm

Oh, my tests I only did after initialization, and I used reserve() to
basically make the vector act like an array, and I used push_back I think...

OK so maybe I forgot a lot of that but I am like 99% certain that once
the vector and array are set up that using [] on the array is no faster
than using [] on the vector, so you can use a vector like an array once
it is set up and there is no problems, and then you can still keep
push_back and resizing and all of those features if you need them.

At least to me it makes sense that way that there is no real penalty
from using vector, or at least any really worth considering "rolling
your own" for.

Jason

Tom Widmer [VC++ MVP] wrote:
> Jason Winnebeck wrote:
>
> The obvious loss for std::vector is that it must copy initialize every
> element - sometimes you only need an uninitialized buffer, since it's
> going to be overwritten anyway. e.g.
>
> int* buffer = new int[1000000];
> std::vector<int> buffer(1000000);
>
> The latter must actually 0 all those ints.
>
> However, I think it would be hard to find an application in which that
> caused a noticeable difference to overall performance...
>
> Tom

Ulrich Eckhardt

2006-03-06, 7:02 pm

yinyang wrote:
> don't now if it helps, but I use simple pointer extension to following
> structure (or class)
>
> class Cint_ptr
> {
> private:
> int* ptr;
> size_t size;
>
> public:
> Cint_ptr(int arr_size):
> size(arr_size)
> {
> ptr = new int[size];
> };
>
> ~Cint_ptr()
> {
> delete [] ptr;
> };
>
> int * getptr()
> {
> return ptr;
> };
>
> size_t getsize()
> {
> return size;
> };
> }
>
> of course you can extend to templates blabla and so on but by storing such
> class instance you can retain array size.


- 'ptr' should be initialized instead of being assigned
- both 'ptr' and 'size' could be constant
- argument to ctor should be a size_t, too
- single-argument ctor should be 'explicit'
- this is a horrible violation of the 'Law of Three'
- zero const correctness
- superfluous semicolons following function definitions (valid C++ though)
- I'd cite boost::scoped_array as alternative to evaluate
- operator[] overload ;)


I do agree that a facility for holding arrays like auto_ptr's is severely
missing and that a small wrapper is already a good step forward towards
writing safe and reliable programs.

Uli

yinyang

2006-03-08, 7:58 am


> - 'ptr' should be initialized instead of being assigned
> - both 'ptr' and 'size' could be constant
> - argument to ctor should be a size_t, too
> - single-argument ctor should be 'explicit'
> - this is a horrible violation of the 'Law of Three'
> - zero const correctness
> - superfluous semicolons following function definitions (valid C++ though)
> - I'd cite boost::scoped_array as alternative to evaluate
> - operator[] overload ;)
>


Great hints, thanx.

yinyang

2006-03-09, 3:59 am

> - this is a horrible violation of the 'Law of Three'

BTW what you mean by that? googling gives me horrible shit...
Ulrich Eckhardt

2006-03-09, 7:58 am

yinyang wrote:
>
> BTW what you mean by that? googling gives me horrible shit...


Well, my google gives quite some good info when I feed it "Law Three C++".

Uli

Sponsored Links







Also available: Server administration forum archive | Web Design forum archive | Software forum archive | Hardware reviews archive

Copyright 2008 codecomments.com