By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
448,651 Members | 1,727 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 448,651 IT Pros & Developers. It's quick & easy.

warning C4267 and warning C4996

P: n/a
I am receiving two warnings in my code and can't figure out why. Will
someone look at this and tell me what I have done wrong?

#include <iostream>

using std::cout;

#include <string>

using std::string;

class PPG{

public:

PPG(char *a, char b, int c)

{ dresscolor =b;

power = c;

setname(a);}//end constructor 1

PPG()

{ setname("Ms. Bellum");

dresscolor ='p';

power = 0;

}//end default constructor

char * getname()const {return name;}
void setname(char *a){

int l =strlen(a);

name = new char[l+1];

strcpy(name,a);

name[l] = '\0';

}//end setname

int getpower() const{return power;}

void setpower(int z){power = z;}

char getdresscolor() const{return dresscolor;}

void setdresscolor(char v){dresscolor=v;}

void print() const

{ cout <<name << " likes to wear ";

switch (dresscolor){

case 'g': case 'G':

cout <<"green dresses. She uses her "; break;

case 'b':case 'B':

cout <<"blue dresses. She uses her ";break;

case 'p': case 'P':

cout <<"pink dresses. She uses her ";

}//end switch

if (power == 1)

cout << "ice breath to defeat her enemies.\n";

else if (power ==2)

cout << "ability to talk to squirrels to confuse evil villians.\n";

else if (power ==3)

cout <<"bad attitude to stop evil doers.\n";

else

cout <<"girl power to rule the world.\n";

}//end print

bool operator==(PPG &ppg)

{ return (strcmp(name, ppg.name)==0); }

private:

char * name;

char dresscolor; //g-reen, b-lue, p-pink

int power; //1-ice breath, 2- squirrel speak, 3-bad attitude

}; //end class

#include "ppg.h"

#include <iostream>

int main()

{

PPG girl1("Bubbles", 'b', 2);

girl1.print();

PPG badgirl("Princess",'g', 4);

badgirl.print();
return 0;

}//end main

These are the warnings I am getting.

warning C4267: 'initializing' : conversion from 'size_t' to 'int', possible
loss of data

warning C4996: 'strcpy' was declared deprecated

I am also getting this.

program files\microsoft visual studio 8\vc\include\string.h(73) : see
declaration of 'strcpy'


Oct 26 '06 #1
Share this Question
Share on Google+
17 Replies


P: n/a
B. Williams wrote:
I am receiving two warnings in my code and can't figure out why. Will
someone look at this and tell me what I have done wrong?
Nothing, really. These are just warnings.
[...]

These are the warnings I am getting.

warning C4267: 'initializing' : conversion from 'size_t' to 'int',
possible loss of data

warning C4996: 'strcpy' was declared deprecated

I am also getting this.

program files\microsoft visual studio 8\vc\include\string.h(73) : see
declaration of 'strcpy'
Stop using C strings and start using 'std::string'.

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
Oct 26 '06 #2

P: n/a
B. Williams wrote:
I am receiving two warnings in my code and can't figure out why. Will
someone look at this and tell me what I have done wrong?

#include <iostream>

using std::cout;

#include <string>

using std::string;

class PPG{

public:

PPG(char *a, char b, int c)

{ dresscolor =b;

power = c;

setname(a);}//end constructor 1

PPG()

{ setname("Ms. Bellum");

dresscolor ='p';

power = 0;

}//end default constructor

char * getname()const {return name;}
void setname(char *a){

int l =strlen(a);

name = new char[l+1];

strcpy(name,a);

name[l] = '\0';

}//end setname

int getpower() const{return power;}

void setpower(int z){power = z;}

char getdresscolor() const{return dresscolor;}

void setdresscolor(char v){dresscolor=v;}

void print() const

{ cout <<name << " likes to wear ";

switch (dresscolor){

case 'g': case 'G':

cout <<"green dresses. She uses her "; break;

case 'b':case 'B':

cout <<"blue dresses. She uses her ";break;

case 'p': case 'P':

cout <<"pink dresses. She uses her ";

}//end switch

if (power == 1)

cout << "ice breath to defeat her enemies.\n";

else if (power ==2)

cout << "ability to talk to squirrels to confuse evil villians.\n";

else if (power ==3)

cout <<"bad attitude to stop evil doers.\n";

else

cout <<"girl power to rule the world.\n";

}//end print

bool operator==(PPG &ppg)

{ return (strcmp(name, ppg.name)==0); }

private:

char * name;

char dresscolor; //g-reen, b-lue, p-pink

int power; //1-ice breath, 2- squirrel speak, 3-bad attitude

}; //end class

#include "ppg.h"

#include <iostream>

int main()

{

PPG girl1("Bubbles", 'b', 2);

girl1.print();

PPG badgirl("Princess",'g', 4);

badgirl.print();
return 0;

}//end main

These are the warnings I am getting.

warning C4267: 'initializing' : conversion from 'size_t' to 'int', possible
loss of data

warning C4996: 'strcpy' was declared deprecated

I am also getting this.

program files\microsoft visual studio 8\vc\include\string.h(73) : see
declaration of 'strcpy'
It is customary to note which line(s) generate the warnings or errors.
I'd also suggest you start indenting your code (your editor can
probably even do it for you -- look under Edit | Advanced, or something
like that in Visual Studio). It makes it MUCH easier to read.

As for the warnings, I'd guess that you're seeing the first when you
assign the result of strlen(), which returns size_t (see
http://www.cppreference.com/stdstring/strlen.html) to an int. The
former type is unsigned, while the latter is signed. You risk losing
the correct length by mixing signed and unsigned types. Change the
variable type to size_t.

The second warning just indicates that strcpy() has been deprecated
because it is unsafe. Use strncpy if you must. Better all around would
be to drop character arrays and C-style string functions altogether in
favor of std::string. That's the C++ way (see
http://www.parashift.com/c++-faq-lit...html#faq-34.1), and it
will handle many of the trickier details for you.

If you must use strcpy (e.g., if your professor or boss requires it for
some inane reason), use a #pragma to disable that message.

Cheers! --M

Oct 26 '06 #3

P: n/a
FYI, Visual Studio's help function is useful in deciphering these
compiler error messages.

Just do Help->Search, and type C4267 into the box, or C4996, or
whatever. You'll get a nice page about what the error is, how to fix
it, etc.

Michael

Oct 26 '06 #4

P: n/a
mlimber wrote:
>
The second warning just indicates that strcpy() has been deprecated
because it is unsafe.
Well, deprecated by Microsoft because some folks at Microsoft think it's
unsafe. Neither the C standard nor the C++ standard has deprecated it,
and there are no plans to do so.

There's nothing wrong with the way strcpy is used in your code. On the
other hand, using the name l for a variable is not so good, because it's
easily confused with 1.

--

-- Pete

Author of "The Standard C++ Library Extensions: a Tutorial and
Reference." For more information about this book, see
www.petebecker.com/tr1book.
Oct 26 '06 #5

P: n/a
B. Williams posted:
warning C4267: 'initializing' : conversion from 'size_t' to 'int',
possible loss of data

If you _really_ want to convert a size_t to an int, then a cast should
suppress such a warning:

int i = (int)strlen(p);

warning C4996: 'strcpy' was declared deprecated

By whom. . . ? "strcpy" is an efficient algorithm and you can presume it
works perfectly on every implementation.

--

Frederick Gotham
Oct 26 '06 #6

P: n/a
Pete Becker wrote:
mlimber wrote:
>>
The second warning just indicates that strcpy() has been deprecated
because it is unsafe.

Well, deprecated by Microsoft because some folks at Microsoft think it's
unsafe. Neither the C standard nor the C++ standard has deprecated it,
and there are no plans to do so.

There's nothing wrong with the way strcpy is used in your code. On the
other hand, using the name l for a variable is not so good, because it's
easily confused with 1.
Whoops, sorry about the misattribution. That last paragraph was meant
for the original poster.

--

-- Pete

Author of "The Standard C++ Library Extensions: a Tutorial and
Reference." For more information about this book, see
www.petebecker.com/tr1book.
Oct 26 '06 #7

P: n/a
Frederick Gotham wrote:
B. Williams posted:
>warning C4267: 'initializing' : conversion from 'size_t' to 'int',
possible loss of data


If you _really_ want to convert a size_t to an int, then a cast should
suppress such a warning:

int i = (int)strlen(p);

>warning C4996: 'strcpy' was declared deprecated


By whom. . . ? "strcpy" is an efficient algorithm and you can presume it
works perfectly on every implementation.
By Microsoft, [SARCASM] in their infinite wisdom [/SARCASM].
Oct 26 '06 #8

P: n/a

Frederick Gotham wrote in message ...
>B. Williams posted:
>warning C4267: 'initializing' : conversion from 'size_t' to 'int',
possible loss of data

If you _really_ want to convert a size_t to an int, then a cast should
suppress such a warning:

int i = (int)strlen(p);
'C' casting? In this NG?

int i = int( strlen(p) );

or use a 'C++' cast.
int len = static_cast<int>( strlen(a) );

or, like elsethread:
size_t len = strlen( a );
// std::size_t len = strlen( a );

Do the "duh!"
int len( 0 );
if( size_t( strlen(a) ) <
static_cast<size_t>(
std::numeric_limits<int>::max() ) ){
len = static_cast<int>( strlen(a) );
}
<G>
--
Bob R
POVrookie
Oct 26 '06 #9

P: n/a
red floyd wrote:
Frederick Gotham wrote:
>B. Williams posted:
>>warning C4267: 'initializing' : conversion from 'size_t' to 'int',
possible loss of data


If you _really_ want to convert a size_t to an int, then a cast should
suppress such a warning:

int i = (int)strlen(p);

>>warning C4996: 'strcpy' was declared deprecated


By whom. . . ? "strcpy" is an efficient algorithm and you can presume it
works perfectly on every implementation.

By Microsoft, [SARCASM] in their infinite wisdom [/SARCASM].
Yeh; and how many people are going to follow thjeir advice and use strncpy
and forget it doesn't guarantee to terminate the string.
--
Bill Medland
Oct 27 '06 #10

P: n/a

Bill Medland wrote:
By whom. . . ? "strcpy" is an efficient algorithm and you can presume it
works perfectly on every implementation.
By Microsoft, [SARCASM] in their infinite wisdom [/SARCASM].
Yeh; and how many people are going to follow thjeir advice and use strncpy
and forget it doesn't guarantee to terminate the string.

Ignoring the issue of whether or not MS depreciating functions like
this is a good thing (in MS's defense, these are functions that have
historically lead to numerous vulnerabilities, this is only a warning
- the functions remain available and behave exactly as expected, and
it's an easy warning to turn off)... At the very least, I think MS
should have avoided the term depreciated.

Actually MS has depreciated strncpy() as well. They recommend (their
new, and obviously non-standard) strcpy_s(), which does deal with the
trailing null as you'd typically expect.

Oct 27 '06 #11

P: n/a


On Oct 26, 8:37 pm, Pete Becker <petebec...@acm.orgwrote:
mlimber wrote:
The second warning just indicates that strcpy() has been deprecated
because it is unsafe.Well, deprecated by Microsoft because some folks at Microsoft think it's
unsafe. Neither the C standard nor the C++ standard has deprecated it,
and there are no plans to do so.
Indeed. To the OP, you can put a #pragma in your project's stdafx.h
file (assuming you are using one) to disable the strcpy warning as it
really is just a Microsoftism (just because _they_ can't use strcpy
safely doesn't mean you can't :-)) . The size_t <int one, whilst
annoying, does make sense. The trouble is that using int for loop
indices is an extremely common idiom; you can either use a pragma to
shut that warning up as well, or you can rewrite your loops to use
size_t / collection<...>::size_type instead of int. I'd recommend the
latter, but opinion seems to be divided.

Oct 27 '06 #12

P: n/a
BobR:

> int i = (int)strlen(p);

'C' casting? In this NG?

Indeed.

int i = int( strlen(p) );

I like how you took a "C cast" as you call it, and disguised it as the
initialisation of a nameless object, very misleading. Try this:

double a = 5.6;

double *p = &a;

int i = int(p);

Why do you prefer your misleading disguised cast to the more recognisible
canonical cast?

or use a 'C++' cast.
int len = static_cast<int>( strlen(a) );

I'd consider that, but it's just too long-winded for my taste.

--

Frederick Gotham
Oct 27 '06 #13

P: n/a
Frederick Gotham wrote:
BobR:

> int i = int( strlen(p) );


I like how you took a "C cast" as you call it, and disguised it as the
initialisation of a nameless object, very misleading.
Not really. The language definition calls this a function-style cast.

--

-- Pete

Author of "The Standard C++ Library Extensions: a Tutorial and
Reference." For more information about this book, see
www.petebecker.com/tr1book.
Oct 27 '06 #14

P: n/a

ro***********@yahoo.com wrote:
Bill Medland wrote:
>By whom. . . ? "strcpy" is an efficient algorithm and you can presume it
>works perfectly on every implementation.
>>
>
By Microsoft, [SARCASM] in their infinite wisdom [/SARCASM].
Yeh; and how many people are going to follow thjeir advice and use strncpy
and forget it doesn't guarantee to terminate the string.


Ignoring the issue of whether or not MS depreciating functions like
this is a good thing (in MS's defense, these are functions that have
historically lead to numerous vulnerabilities, this is only a warning
- the functions remain available and behave exactly as expected, and
it's an easy warning to turn off)... At the very least, I think MS
should have avoided the term depreciated.

Actually MS has depreciated strncpy() as well. They recommend (their
new, and obviously non-standard) strcpy_s(), which does deal with the
trailing null as you'd typically expect.
Microsoft states std::copy algorithm is deprecated too.

I am sure I'd go postal if I was a M$ employee

Oct 27 '06 #15

P: n/a

Frederick Gotham wrote in message ...
>BobR:
>> int i = (int)strlen(p);
'C' casting? In this NG?
int i = int( strlen(p) );

I like how you took a "C cast" as you call it, and disguised it as the
initialisation of a nameless object, very misleading. Try this:

double a = 5.6;
double *p = &a;
int i = int(p);

Why do you prefer your misleading disguised cast to the more recognisible
canonical cast?
{
double a = 5.6;
double *p = &a;

int i = int(p);
int ia = int(*p);

std::cout <<" double a="<<a<< std::endl;
std::cout <<" int i = int(p)="<<i<< std::endl;
std::cout <<" int ia = int(*p)="<<ia<< std::endl;
}
/* -- output --
double a=5.600000
int i = int(p)=10611788 // <-- address (in decimal)(maybe truncated)
int ia = int(*p)=5 // <-- value p was 'pointing to'
*/

Works fine for me. Sure, some care must be taken, but, is the 'C' cast any
safer? (I find them much less safe in some cases. (to-from 'void*').
>
>or use a 'C++' cast.
int len = static_cast<int>( strlen(a) );

I'd consider that, but it's just too long-winded for my taste.
But, I think that is the point. It stands out like a sore thumb. It says,
"HEY, are you really positive you *need* to cast this?". And
'reinterpret_cast<>' is even more typing, saying, "danger, please double
check your design, and what you are casting from-to.".

I'm not trying to argue or piss you off (I value your opinion/knowledge).
Might be some newbie lurkers reading here that should have the choice.

--
Bob R
POVrookie
Oct 27 '06 #16

P: n/a
BobR:
{
double a = 5.6;
double *p = &a;

int i = int(p);
int ia = int(*p);

std::cout <<" double a="<<a<< std::endl;
std::cout <<" int i = int(p)="<<i<< std::endl;
std::cout <<" int ia = int(*p)="<<ia<< std::endl;
}
/* -- output --
double a=5.600000
int i = int(p)=10611788 // <-- address (in decimal)(maybe truncated)
int ia = int(*p)=5 // <-- value p was 'pointing to'
*/

Works fine for me. Sure, some care must be taken, but, is the 'C' cast
any
safer? (I find them much less safe in some cases. (to-from 'void*').

My intent was to demonstrate that they're exactly equivalent. The following
two statements are exactly equivalent regardless of the types used:

Type1 obj1 = (Type1)obj2;

Type1 obj1 = Type1(obj2);

Just because you've switched around some parentheses, doesn't make it any
"safer". The first one looks like a cast, so I use it when I want a cast.
The second looks like the initialisation of a nameless object, so I use it
when I want a nameless object.

But, I think that is the point. It stands out like a sore thumb. It says,
"HEY, are you really positive you *need* to cast this?". And
'reinterpret_cast<>' is even more typing, saying, "danger, please double
check your design, and what you are casting from-to.".

I don't share your caution. I use casts quite a lot to achieve what I want;
if there was something wrong with them, I wouldn't use them. The following
is perfectly okay for me:

int i = 5;
short a = (short)i; /* Cast to suppress warning */

I only resort to the more verbose casts when the cast in question is more
complex than simply converting one kind of intrinsic to another.

I'm not trying to argue or piss you off (I value your opinion/knowledge).
Might be some newbie lurkers reading here that should have the choice.

No bother.

--

Frederick Gotham
Oct 27 '06 #17

P: n/a

Diego Martins wrote:
Microsoft states std::copy algorithm is deprecated too.

Only for unchecked itterators, IIRC.

Oct 27 '06 #18

This discussion thread is closed

Replies have been disabled for this discussion.