how to deal with the translation from "const char * " to "const unsigned char *"?

Discussion in 'C++' started by =?gb2312?B?wNbA1rTzzOzKpg==?=, Jan 29, 2007.

  1. i wrote:
    -----------------------------------------------------------------------
    ----------------------------------------
    unsigned char * p = reinterpret_cast<unsigned char *>("abcdg");
    sizeof(reinterpret_cast<const char *>(p));
    -----------------------------------------------------------------------
    ----------------------------------------

    the compiler tells me that "reinterpret_cast from type "const char * "
    to type "unsigned char *" casts away constness "
     
    =?gb2312?B?wNbA1rTzzOzKpg==?=, Jan 29, 2007
    #1
    1. Advertising

  2. =?gb2312?B?wNbA1rTzzOzKpg==?=

    Kaz Kylheku Guest

    On Jan 28, 11:21 pm, "ä¹ä¹å¤§å¤©å¸ˆ" <> wrote:
    > i wrote:-----------------------------------------------------------------------
    > ----------------------------------------
    > unsigned char * p = reinterpret_cast<unsigned char *>("abcdg");
    > sizeof(reinterpret_cast<const char *>(p));
    > -----------------------------------------------------------------------
    > ----------------------------------------
    >
    > the compiler tells me that "reinterpret_cast from type "const char * "
    > to type "unsigned char *" casts away constness "


    At this point you stop wrestling with the C++ bullshit and just use a
    C style cast.

    The good old C style cast will implicitly produce the correct
    combination of reinterpret_cast and static_cast, without the verbiage
    cluttering your code.

    Since no typedef names are involved whose meanings could change, the C
    style cast is no less safe than the new style cast combination, and is
    much more readable.

    (If you use the C cast with abstracted types, like casting some A * to
    some B *, the danger is that someone may redefine what A and B is, and
    the cast will silently continue to work, even though the change may be
    such that the conversion has erroneous consequences).
     
    Kaz Kylheku, Jan 29, 2007
    #2
    1. Advertising

  3. =?gb2312?B?wNbA1rTzzOzKpg==?=

    Kai-Uwe Bux Guest

    ????? wrote:

    > i wrote:
    > -----------------------------------------------------------------------
    > ----------------------------------------
    > unsigned char * p = reinterpret_cast<unsigned char *>("abcdg");
    > sizeof(reinterpret_cast<const char *>(p));
    > -----------------------------------------------------------------------
    > ----------------------------------------
    >
    > the compiler tells me that "reinterpret_cast from type "const char * "
    > to type "unsigned char *" casts away constness "


    In the code you posted, you do not cast to "const unsigned char *". Try:

    unsigned char const * p = static_cast<unsigned char const *>("abcdg");


    Best

    Kai-Uwe Bux
     
    Kai-Uwe Bux, Jan 29, 2007
    #3
  4. Re: how to deal with the translation from "const char * " to "constunsigned char *"?

    ä¹ä¹å¤§å¤©å¸ˆ wrote:
    > i wrote:
    > -----------------------------------------------------------------------
    > ----------------------------------------
    > unsigned char * p = reinterpret_cast<unsigned char *>("abcdg");
    > sizeof(reinterpret_cast<const char *>(p));
    > -----------------------------------------------------------------------
    > ----------------------------------------
    >
    > the compiler tells me that "reinterpret_cast from type "const char * "
    > to type "unsigned char *" casts away constness "
    >



    The compiler is right. "unsigned char *" is non-const and string
    literals (like "abcdg") are const.


    If you're casting to a "unsigned char *" you need to ask yourself why.
    Will it be modified after the cast ? (that would be undefined and toast
    your process on some platforms)

    It seems like you have a design problem.
     
    Gianni Mariani, Jan 29, 2007
    #4
  5. =?gb2312?B?wNbA1rTzzOzKpg==?=

    Noah Roberts Guest

    Re: how to deal with the translation from "const char * " to "constunsigned char *"?

    Gianni Mariani wrote:
    > ä¹ä¹å¤§å¤©å¸ˆ wrote:
    >> i wrote:
    >> -----------------------------------------------------------------------
    >> ----------------------------------------
    >> unsigned char * p = reinterpret_cast<unsigned char *>("abcdg");
    >> sizeof(reinterpret_cast<const char *>(p));
    >> -----------------------------------------------------------------------
    >> ----------------------------------------
    >>
    >> the compiler tells me that "reinterpret_cast from type "const char * "
    >> to type "unsigned char *" casts away constness "
    >>

    >
    >
    > The compiler is right. "unsigned char *" is non-const and string
    > literals (like "abcdg") are const.


    It always intrigues me that such distinction is made in cases like this
    yet this is perfectly ok from a legal point of view:

    char * x = "I'm const";
     
    Noah Roberts, Jan 29, 2007
    #5
  6. Re: how to deal with the translation from "const char * " to "constunsigned char *"?

    Noah Roberts wrote:
    > Gianni Mariani wrote:

    ....
    >
    > It always intrigues me that such distinction is made in cases like this
    > yet this is perfectly ok from a legal point of view:
    >
    > char * x = "I'm const";


    Yes, sigh. I think the standard's commitee made a blunder on that one.

    This is due to a rather short sighted view that there was a large legacy
    code base that would break if that was not allowed. At a guess, I think
    this would not be in the standard as an exception if hindsight was
    available.
     
    Gianni Mariani, Jan 29, 2007
    #6
  7. =?gb2312?B?wNbA1rTzzOzKpg==?=

    Grizlyk Guest

    Gianni Mariani wrote:
    >>
    >> unsigned char * p = reinterpret_cast<unsigned char *>("abcdg");
    >>
    >> the compiler tells me that "reinterpret_cast from type "const char * " to
    >> type "unsigned char *" casts away constness "

    >
    > The compiler is right. "unsigned char *" is non-const and string literals
    > (like "abcdg") are const.
    >
    >
    > If you're casting to a "unsigned char *" you need to ask yourself why.


    I think, the following expression
    unsigned char * p = static_cast<unsigned char *>( const_cast<char*>
    ("abcdg") );
    is not work because sizeof("type") can be not equal to sizeof("unsigned
    type") in theory,

    Assuming on your target sizeof("type")==sizeof("unsigned type")

    If "p" is _not_ const because there is old library parameter here and you
    are shure, that "p" is always using as "const unsigned char *" you can apply
    C-style cast
    (unsigned char *) ("abcdg")"
    or reinterpret_cast<>
    unsigned char * p = reinterpret_cast<unsigned char *>( const_cast<char*>
    ("abcdg") );

    else you can create a temporary storage

    const char data[]="abcdg";
    char buf[sizeof(data)]; strcpy(buf,data);
    unsigned char * p = reinterpret_cast<unsigned char *>( buf );

    --
    Maksim A Polyanin
     
    Grizlyk, Jan 29, 2007
    #7
  8. =?gb2312?B?wNbA1rTzzOzKpg==?=

    Grizlyk Guest

    Grizlyk wrote:

    > or reinterpret_cast<>
    > unsigned char * p = reinterpret_cast<unsigned char *>(
    > const_cast<char*> ("abcdg") );


    And i forget cast via "void*"

    unsigned char * p = static_cast<void*> ("abcdg");

    --
    Maksim A Polyanin
     
    Grizlyk, Jan 29, 2007
    #8
  9. =?gb2312?B?wNbA1rTzzOzKpg==?=

    Grizlyk Guest

    Grizlyk wrote:
    >> or reinterpret_cast<>
    >> unsigned char * p = reinterpret_cast<unsigned char *>(
    >> const_cast<char*> ("abcdg") );

    >
    > And i forget cast via "void*"
    >
    > unsigned char * p = static_cast<void*> ("abcdg");


    No, can not, i was wrong, better to do like this

    void *const tmp = const_cast<char*>("abcdg");
    unsigned char *p = static_cast<unsigned char*>(tmp);

    --
    Maksim A Polyanin
     
    Grizlyk, Jan 29, 2007
    #9
  10. =?gb2312?B?wNbA1rTzzOzKpg==?=

    Rolf Magnus Guest

    Kaz Kylheku wrote:

    >
    >
    > On Jan 28, 11:21 pm, "ä¹ä¹å¤§å¤©å¸ˆ" <> wrote:
    >> i
    >>

    wrote:-----------------------------------------------------------------------
    >> ---------------------------------------- unsigned char * p =
    >> reinterpret_cast<unsigned char *>("abcdg"); sizeof(reinterpret_cast<const
    >> char *>(p));
    >> -----------------------------------------------------------------------
    >> ----------------------------------------
    >>
    >> the compiler tells me that "reinterpret_cast from type "const char * "
    >> to type "unsigned char *" casts away constness "

    >
    > At this point you stop wrestling with the C++ bullshit and just use a
    > C style cast.


    No. At this point you think thrice about letting a pointer to non-const
    point to a string literal, and twice about letting a pointer to unsigned
    char point to a char.
    For the second, there is rarely a reason. For the first, the only reason I
    can think of is to deal with legacy code that isn't const correct.

    > The good old C style cast will implicitly produce the correct
    > combination of reinterpret_cast and static_cast, without the verbiage
    > cluttering your code.


    No. Rather it produces any combination that will somehow make the target
    type from the supplied object. It doesn't magically know if that's the
    correct one. So better explicitly tell the compiler which conversion you
    actually want.

    > Since no typedef names are involved whose meanings could change, the C
    > style cast is no less safe than the new style cast combination, and is
    > much more readable.


    Well, with the C style cast, the OP wouldn't have noticed that he let a
    non-const pointer point to something that is const and must not be changed.
    The compiler would have silently accepted the erroneous code.

    > (If you use the C cast with abstracted types, like casting some A * to
    > some B *, the danger is that someone may redefine what A and B is, and
    > the cast will silently continue to work, even though the change may be
    > such that the conversion has erroneous consequences).


    It always does silently whatever it takes, so it's always dangerous.
     
    Rolf Magnus, Jan 29, 2007
    #10
  11. Re: how to deal with the translation from "const char * " to "constunsigned char *"?

    Gianni Mariani a écrit :
    > Noah Roberts wrote:
    >> Gianni Mariani wrote:

    > ...
    >>
    >> It always intrigues me that such distinction is made in cases like this
    >> yet this is perfectly ok from a legal point of view:
    >>
    >> char * x = "I'm const";

    >
    > Yes, sigh. I think the standard's commitee made a blunder on that one.
    >
    > This is due to a rather short sighted view that there was a large legacy
    > code base that would break if that was not allowed. At a guess, I think
    > this would not be in the standard as an exception if hindsight was
    > available.


    The standard comitee didn't want to constraint compilers with putting
    the array in a rw area.
    The compiler is free to put in ro and save some copy time. The array can
    even be shared among other part of the program.

    That is a reason why casting away the consteness is undefined in this
    case and should not be done.

    Michael
     
    Michael DOUBEZ, Jan 29, 2007
    #11
  12. =?gb2312?B?wNbA1rTzzOzKpg==?=

    Rolf Magnus Guest

    Michael DOUBEZ wrote:

    > Gianni Mariani a écrit :
    >> Noah Roberts wrote:
    >>> Gianni Mariani wrote:

    >> ...
    >>>
    >>> It always intrigues me that such distinction is made in cases like this
    >>> yet this is perfectly ok from a legal point of view:
    >>>
    >>> char * x = "I'm const";

    >>
    >> Yes, sigh. I think the standard's commitee made a blunder on that one.
    >>
    >> This is due to a rather short sighted view that there was a large legacy
    >> code base that would break if that was not allowed. At a guess, I think
    >> this would not be in the standard as an exception if hindsight was
    >> available.

    >
    > The standard comitee didn't want to constraint compilers with putting
    > the array in a rw area.
    > The compiler is free to put in ro and save some copy time. The array can
    > even be shared among other part of the program.


    What does this have to do with the choice to allow letting a pointer to
    non-const point to string literals without a cast?

    > That is a reason why casting away the consteness is undefined in this
    > case and should not be done.


    Casting away constness isn't undefined. Only writing to an object that was
    initially declared const is.
     
    Rolf Magnus, Jan 29, 2007
    #12
  13. Re: how to deal with the translation from "const char * " to "constunsigned char *"?

    Michael DOUBEZ a écrit :
    > Gianni Mariani a écrit :
    >> Noah Roberts wrote:
    >>> Gianni Mariani wrote:

    >> ...
    >>>
    >>> It always intrigues me that such distinction is made in cases like this
    >>> yet this is perfectly ok from a legal point of view:
    >>>
    >>> char * x = "I'm const";

    >>
    >> Yes, sigh. I think the standard's commitee made a blunder on that one.
    >>
    >> This is due to a rather short sighted view that there was a large
    >> legacy code base that would break if that was not allowed. At a
    >> guess, I think this would not be in the standard as an exception if
    >> hindsight was available.

    >
    > The standard comitee didn't want to constraint compilers with putting
    > the array in a rw area.
    > The compiler is free to put in ro and save some copy time. The array can
    > even be shared among other part of the program.
    >
    > That is a reason why casting away the consteness is undefined in this
    > case and should not be done.


    In fact, it is legacy code that allowed this writing because string use
    to be defaulted as char[] and automaticaly casted to char*.
    And the standard changed the type of string to const char[] and thus
    strings can now only be automatically casted into const char*.

    Michael
     
    Michael DOUBEZ, Jan 29, 2007
    #13
  14. Re: how to deal with the translation from "const char * " to "constunsigned char *"?

    Rolf Magnus a écrit :
    > Michael DOUBEZ wrote:
    >
    >> The standard comitee didn't want to constraint compilers with putting
    >> the array in a rw area.
    >> The compiler is free to put in ro and save some copy time. The array can
    >> even be shared among other part of the program.

    >
    > What does this have to do with the choice to allow letting a pointer to
    > non-const point to string literals without a cast?


    Why would you be allowed to cast it to not const if not to be able to
    modify it ?
    And if it is done automatically, there is the risk you modify the string
    without remebering it is const.

    >
    >> That is a reason why casting away the consteness is undefined in this
    >> case and should not be done.

    >
    > Casting away constness isn't undefined. Only writing to an object that was
    > initially declared const is.
    >


    Yes, writing is undefined; that is what I meant.

    Michael
     
    Michael DOUBEZ, Jan 29, 2007
    #14
  15. =?gb2312?B?wNbA1rTzzOzKpg==?=

    Andre Kostur Guest

    "Grizlyk" <> wrote in news:epkdp5$emk$:

    > Gianni Mariani wrote:
    >>>
    >>> unsigned char * p = reinterpret_cast<unsigned char *>("abcdg");
    >>>
    >>> the compiler tells me that "reinterpret_cast from type "const char *
    >>> " to type "unsigned char *" casts away constness "

    >>
    >> The compiler is right. "unsigned char *" is non-const and string
    >> literals (like "abcdg") are const.
    >>
    >>
    >> If you're casting to a "unsigned char *" you need to ask yourself
    >> why.

    >
    > I think, the following expression
    > unsigned char * p = static_cast<unsigned char *>(
    > const_cast<char*>
    > ("abcdg") );
    > is not work because sizeof("type") can be not equal to
    > sizeof("unsigned type") in theory,


    So? That code is casting pointers-to-object. The pointer size won't
    change, regardless of the size of the pointed to object.
     
    Andre Kostur, Jan 29, 2007
    #15
  16. =?gb2312?B?wNbA1rTzzOzKpg==?=

    Grizlyk Guest

    Andre Kostur wrote:
    >> I think, the following expression
    >> unsigned char * p =
    >> static_cast<unsigned char *>
    >> (
    >> const_cast<char*>("abcdg")
    >> );
    >> is do not work because sizeof("type") can be not equal
    >> to sizeof("unsigned type") in theory

    >
    > So? That code is casting pointers-to-object. The pointer size won't
    > change, regardless of the size of the pointed to object.


    I am not shure (i have no standard) that pointers for all types must have
    fixed sizeof() (as "int" for example) or unsigned type must have the same
    sizeof() as signed type.

    For example there are memory models, where "sizeof(char *_far)==4", but
    "sizeof(char *)==2".

    Let pointers have fixed sizeof() and sizeof("type")!=sizeof("unsigned
    type"). Here pointer arithmetic can be changed, because value of next
    pointer (++ptr) is depending from size of object pointer point to.

    For example:

    int *i=0;
    ++i; //value of i is 4

    char *c=0;
    ++c; //value of c is 1

    //assuming sizeof(int)!=sizeof(unsigned)
    unsigned *u=0;
    ++u; //value of u is 8

    --
    Maksim A Polyanin
     
    Grizlyk, Jan 29, 2007
    #16
  17. =?gb2312?B?wNbA1rTzzOzKpg==?=

    Andre Kostur Guest

    "Grizlyk" <> wrote in news:epl9fa$f00$:

    > Andre Kostur wrote:
    >>> I think, the following expression
    >>> unsigned char * p =
    >>> static_cast<unsigned char *>
    >>> (
    >>> const_cast<char*>("abcdg")
    >>> );
    >>> is do not work because sizeof("type") can be not equal
    >>> to sizeof("unsigned type") in theory

    >>
    >> So? That code is casting pointers-to-object. The pointer size won't
    >> change, regardless of the size of the pointed to object.

    >
    > I am not shure (i have no standard) that pointers for all types must
    > have fixed sizeof() (as "int" for example) or unsigned type must have
    > the same sizeof() as signed type.
    >
    > For example there are memory models, where "sizeof(char *_far)==4",
    > but "sizeof(char *)==2".


    sizeof(char * _far) is a non-standard type, and thus is implementation-
    dependant. All Standard pointers-to-object have the same size.

    > Let pointers have fixed sizeof() and sizeof("type")!=sizeof("unsigned
    > type"). Here pointer arithmetic can be changed, because value of next
    > pointer (++ptr) is depending from size of object pointer point to.


    Pointer arithmetic has nothing to do with sizeof(T*). But is related to
    sizeof(T).
     
    Andre Kostur, Jan 29, 2007
    #17
  18. =?gb2312?B?wNbA1rTzzOzKpg==?=

    Noah Roberts Guest

    Re: how to deal with the translation from "const char * " to "constunsigned char *"?

    Michael DOUBEZ wrote:
    > Rolf Magnus a écrit :
    >> Michael DOUBEZ wrote:
    >>
    >>> The standard comitee didn't want to constraint compilers with putting
    >>> the array in a rw area.
    >>> The compiler is free to put in ro and save some copy time. The array can
    >>> even be shared among other part of the program.

    >>
    >> What does this have to do with the choice to allow letting a pointer to
    >> non-const point to string literals without a cast?

    >
    > Why would you be allowed to cast it to not const if not to be able to
    > modify it ?
    > And if it is done automatically, there is the risk you modify the string
    > without remebering it is const.


    I think you've missed the point. The compiler will not complain about
    code that does this:

    char * x = "hello";
    x[2] = 't';

    You'll only get a warning when you try to run the program...if
    then...maybe only when you create your release compile with its
    optimizations...maybe a customer will find it.

    The standard requires that this is ok. It is undefined, even in C where
    it comes from, but there can be no diagnostic. Most people would like
    to get the usual error about attempting to assign const to non-const
    without a cast, but you don't get that in this one special case. Allows
    for all sorts of unfortunate errors.
     
    Noah Roberts, Jan 29, 2007
    #18
  19. =?gb2312?B?wNbA1rTzzOzKpg==?=

    Daniel T. Guest

    In article <epkdp5$emk$>, "Grizlyk" <>
    wrote:

    > Gianni Mariani wrote:
    > >>
    > >> unsigned char * p = reinterpret_cast<unsigned char *>("abcdg");
    > >>
    > >> the compiler tells me that "reinterpret_cast from type "const char * " to
    > >> type "unsigned char *" casts away constness "

    > >
    > > The compiler is right. "unsigned char *" is non-const and string literals
    > > (like "abcdg") are const.
    > >
    > >
    > > If you're casting to a "unsigned char *" you need to ask yourself why.

    >
    > I think, the following expression
    > unsigned char * p = static_cast<unsigned char *>( const_cast<char*>
    > ("abcdg") );
    > is not work because sizeof("type") can be not equal to sizeof("unsigned
    > type") in theory,


    AFAIK, the above is incorrect. sizeof( "unsigned type" ) always equals
    sizeof( "type" )
     
    Daniel T., Jan 29, 2007
    #19
  20. =?gb2312?B?wNbA1rTzzOzKpg==?=

    Rolf Magnus Guest

    Andre Kostur wrote:

    > "Grizlyk" <> wrote in news:epkdp5$emk$:
    >
    >> Gianni Mariani wrote:
    >>>>
    >>>> unsigned char * p = reinterpret_cast<unsigned char *>("abcdg");
    >>>>
    >>>> the compiler tells me that "reinterpret_cast from type "const char *
    >>>> " to type "unsigned char *" casts away constness "
    >>>
    >>> The compiler is right. "unsigned char *" is non-const and string
    >>> literals (like "abcdg") are const.
    >>>
    >>>
    >>> If you're casting to a "unsigned char *" you need to ask yourself
    >>> why.

    >>
    >> I think, the following expression
    >> unsigned char * p = static_cast<unsigned char *>(
    >> const_cast<char*>
    >> ("abcdg") );
    >> is not work because sizeof("type") can be not equal to
    >> sizeof("unsigned type") in theory,

    >
    > So? That code is casting pointers-to-object. The pointer size won't
    > change, regardless of the size of the pointed to object.


    Well, but using a pointer for accessing an object of a size different from
    the pointed-to type might lead to trouble if you aren't prepared for it.

    Btw: Different pointer types might also have different sizes.
     
    Rolf Magnus, Jan 29, 2007
    #20
    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. rbt

    deal or no deal

    rbt, Dec 22, 2005, in forum: Python
    Replies:
    7
    Views:
    597
    Duncan Smith
    Dec 28, 2005
  2. Replies:
    24
    Views:
    905
    Netocrat
    Oct 30, 2005
  3. lovecreatesbeauty
    Replies:
    1
    Views:
    1,151
    Ian Collins
    May 9, 2006
  4. Alex Vinokur
    Replies:
    9
    Views:
    832
    James Kanze
    Oct 13, 2008
  5. RjY
    Replies:
    6
    Views:
    2,543
    Kaz Kylheku
    Dec 15, 2009
Loading...

Share This Page