warning C4267 and warning C4996

Discussion in 'C++' started by B. Williams, Oct 26, 2006.

  1. B. Williams

    B. Williams Guest

    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'
    B. Williams, Oct 26, 2006
    #1
    1. Advertising

  2. 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
    Victor Bazarov, Oct 26, 2006
    #2
    1. Advertising

  3. B. Williams

    mlimber Guest

    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-lite/containers.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
    mlimber, Oct 26, 2006
    #3
  4. B. Williams

    Michael Guest

    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
    Michael, Oct 26, 2006
    #4
  5. B. Williams

    Pete Becker Guest

    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.
    Pete Becker, Oct 26, 2006
    #5
  6. 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
    Frederick Gotham, Oct 26, 2006
    #6
  7. B. Williams

    Pete Becker Guest

    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.
    Pete Becker, Oct 26, 2006
    #7
  8. B. Williams

    red floyd Guest

    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].
    red floyd, Oct 26, 2006
    #8
  9. B. Williams

    BobR Guest

    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
    BobR, Oct 26, 2006
    #9
  10. B. Williams

    Bill Medland Guest

    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
    Bill Medland, Oct 27, 2006
    #10
  11. B. Williams

    Guest

    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, 2006
    #11
  12. On Oct 26, 8:37 pm, 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.
    >


    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.
    tragomaskhalos, Oct 27, 2006
    #12
  13. 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
    Frederick Gotham, Oct 27, 2006
    #13
  14. B. Williams

    Pete Becker Guest

    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.
    Pete Becker, Oct 27, 2006
    #14
  15. 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
    Diego Martins, Oct 27, 2006
    #15
  16. B. Williams

    BobR Guest

    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
    BobR, Oct 27, 2006
    #16
  17. 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
    Frederick Gotham, Oct 27, 2006
    #17
  18. B. Williams

    Guest

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



    Only for unchecked itterators, IIRC.
    , Oct 27, 2006
    #18
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Pete Becker
    Replies:
    0
    Views:
    1,373
    Pete Becker
    Feb 10, 2005
  2. =?Utf-8?B?cGF0cmlja2RyZA==?=

    masterpages and secure and nonsecure items warning

    =?Utf-8?B?cGF0cmlja2RyZA==?=, Jun 14, 2007, in forum: ASP .Net
    Replies:
    10
    Views:
    823
    Alan Silver
    Jun 18, 2007
  3. webking

    warning C4996: 'fopen' vs 'fopen_s'

    webking, Jul 8, 2008, in forum: C Programming
    Replies:
    0
    Views:
    5,958
    webking
    Jul 8, 2008
  4. WARNING! Prosoftstore.com is a SCAM! WARNING!

    , Jul 8, 2007, in forum: ASP .Net Web Services
    Replies:
    0
    Views:
    314
  5. Julian Mehnle
    Replies:
    17
    Views:
    866
    Julian Mehnle
    May 18, 2006
Loading...

Share This Page