pointer questions

Discussion in 'C Programming' started by tfelb, Oct 17, 2008.

  1. tfelb

    tfelb Guest

    Hey group!

    I have 2 questions. I saw functions with char *dst = (char *)src. In
    that case if I remember what I've learned I assign (an) (the) address
    of src to dst. Right?

    But I can assign an address with the address operator & too? char *dst
    = &src.

    What's the difference between *dst = (char *)src and *dst = &src and
    what's the recommended style?

    2. The same thing with returning a pointer from a function. If i write
    a version of strchr i can return a pointer like

    return ptr OR
    return (char *)ptr.

    I would think in both cases I'll return a pointer(address)

    Thanks for any help

    Tom
     
    tfelb, Oct 17, 2008
    #1
    1. Advertising

  2. tfelb

    James Kuyper Guest

    tfelb wrote:
    > Hey group!
    >
    > I have 2 questions. I saw functions with char *dst = (char *)src. In
    > that case if I remember what I've learned I assign (an) (the) address
    > of src to dst. Right?
    >
    > But I can assign an address with the address operator & too? char *dst
    > = &src.
    >
    > What's the difference between *dst = (char *)src and *dst = &src and
    > what's the recommended style?


    It's not a minor style difference, it's a profound difference in
    meaning. However, there's also some confusion in what you've written
    between declarations and statements. Let me clear up that issue before
    going any further. You wrote two very different things that look similar:

    char *dst = (char*)src;

    This is a declaration of a pointer to char named 'dst'. It is
    initialized by converting src into a pointer to char. That pointer value
    is stored in dst.

    You also mentioned:

    *dst = (char*)src;

    This is an assignment statement. It takes a pointer named dst,
    determines what that pointer points at, and then sets the thing that it
    points at equal to (char*)src.

    So, the declaration sets the value of 'dst'. The assignment statement
    sets the value of the thing that dst points at. These are two very
    different things.

    (char*)src and &src mean two very different things. In this context, src
    is probably a pointer object, whose value is a pointer that points at
    some other object (if it's a void*, it might point at itself, but this
    is easier to explain if we assume that it doesn't). (char*)src converts
    that pointer value into a pointer to char, which will point to the first
    byte of whatever object src points at. In contrast, &src creates a
    pointer value, which points at src itself, not at the object that src
    points at. You're earlier declaration implies that src is a pointer
    type, let's call it a T*. Then &src has the type T**. That's not a type
    that can be used to initialize the value of dst.


    > 2. The same thing with returning a pointer from a function. If i write
    > a version of strchr i can return a pointer like
    >
    > return ptr OR
    > return (char *)ptr.


    The key thing you need to understand about casts is that they are almost
    never necessary. Most safe conversions occur implicitly, without you
    having to make them explicit by using a cast. Using a cast can hide a
    type error, so they should be avoided except when they are actually
    necessary.

    For most operators, when the two operands need to be the same type, the
    "usual arithmetic conversions" (6.3.1.8) happen automatically, to make
    them have the same type. When you assign a value to an object, if the
    value is not of the same type as the object, it is usually implicitly
    converted to the type of the object. The same is true in the definition
    of an object, if it is explicitly initialized. It also happens to when
    arguments are passed to a function, if that function is declared with a
    prototype. Getting back to your question, the implicit conversions also
    occur when a function returns a value.

    You need a cast if there is no implicit conversion allowed from the
    source type to the destination type. You also need a cast if the
    implicit conversion is allowed, but would produce a different result
    than the conversion that you want to perform. However, these are the
    only two cases where a cast is needed, and you should always be
    suspicious of the possibility that any cast you read, or are thinking of
    writing, might be either unnecessary, or possibly even an error.
     
    James Kuyper, Oct 17, 2008
    #2
    1. Advertising

  3. tfelb

    tfelb Guest

    On 17 Okt., 15:01, James Kuyper <> wrote:
    > tfelb wrote:
    > > Hey group!

    >
    > > I have 2 questions. I saw  functions with char *dst = (char *)src. In
    > > that case if I remember what I've learned I assign (an) (the) address
    > > of src to dst. Right?

    >
    > > But I can assign an address with the address operator & too? char *dst
    > > = &src.

    >
    > > What's the difference between *dst = (char *)src and *dst = &src and
    > > what's the recommended style?

    >
    > It's not a minor style difference, it's a profound difference in
    > meaning. However, there's also some confusion in what you've written
    > between declarations and statements. Let me clear up that issue before
    > going any further. You wrote two very different things that look similar:
    >
    >         char *dst = (char*)src;
    >
    > This is a declaration of a pointer to char named 'dst'. It is
    > initialized by converting src into a pointer to char. That pointer value
    > is stored in dst.
    >
    > You also mentioned:
    >
    >         *dst = (char*)src;
    >
    > This is an assignment statement. It takes a pointer named dst,
    > determines what that pointer points at, and then sets the thing that it
    > points at equal to (char*)src.
    >
    > So, the declaration sets the value of 'dst'. The assignment statement
    > sets the value of the thing that dst points at. These are two very
    > different things.
    >
    > (char*)src and &src mean two very different things. In this context, src
    > is probably a pointer object, whose value is a pointer that points at
    > some other object (if it's a void*, it might point at itself, but this
    > is easier to explain if we assume that it doesn't). (char*)src converts
    > that pointer value into a pointer to char, which will point to the first
    > byte of whatever object src points at. In contrast, &src creates a
    > pointer value, which points at src itself, not at the object that src
    > points at. You're earlier declaration implies that src is a pointer
    > type,  let's call it a T*. Then &src has the type T**. That's not a type
    > that can be used to initialize the value of dst.
    >
    > > 2. The same thing with returning a pointer from a function. If i write
    > > a version of strchr i can return a pointer like

    >
    > > return ptr OR
    > > return (char *)ptr.

    >
    > The key thing you need to understand about casts is that they are almost
    > never necessary. Most safe conversions occur implicitly, without you
    > having to make them explicit by using a cast. Using a cast can hide a
    > type error, so they should be avoided except when they are actually
    > necessary.
    >
    > For most operators, when the two operands need to be the same type, the
    > "usual arithmetic conversions" (6.3.1.8) happen automatically, to make
    > them have the same type. When you assign a value to an object, if the
    > value is not of the same type as the object, it is usually implicitly
    > converted to the type of the object. The same is true in the definition
    > of an object, if it is explicitly initialized. It also happens to when
    > arguments are passed to a function, if that function is declared with a
    > prototype. Getting  back to your question, the implicit conversions also
    > occur when a function returns a value.
    >
    > You need a cast if there is no implicit conversion allowed from the
    > source type to the destination type. You also need a cast if the
    > implicit conversion is allowed, but would produce a different result
    > than the conversion that you want to perform. However, these are the
    > only two cases where a cast is needed, and you should always be
    > suspicious of the possibility that any cast you read, or are thinking of
    > writing, might be either unnecessary, or possibly even an error.


    Thanks for the replies, I think I understand you. If i would say that
    in easy words (I'm not an expert :) )*dst = (char *)src is simply a
    casting(conversion) if 2 pointer variables have different types (for
    example the conversion from a void * pointer to a char *).

    *dst = &src is the intializing process of dst but only if src has the
    type char *. If not then I'll need the conversion.

    Tom F.
     
    tfelb, Oct 17, 2008
    #3
  4. tfelb

    James Kuyper Guest

    tfelb wrote:
    ....
    > Thanks for the replies, I think I understand you. If i would say that
    > in easy words (I'm not an expert :) )*dst = (char *)src is simply a
    > casting(conversion) if 2 pointer variables have different types (for
    > example the conversion from a void * pointer to a char *).


    You need to understand the difference between conversion and casting. In
    this context, conversion is the creation of a value of one type from a
    value that is of a different type. Casting is the process of explicitly
    ordering that a conversion must occur, in this case by using the cast
    (char*). Conversion can also occur without a cast; in fact, you're
    usually better off letting it happen implicitly, if it can happen
    implicitly. If, for instance, src is a void* pointer, then the following
    definition:

    char *dst = src;

    will convert src implicitly to char*, no cast is needed.

    You're incorrect in saying that 2 pointer variable are converted by the
    statement you refer to. Only the value of one variable is converted by
    that statement - the value of src.

    > *dst = &src is the intializing process of dst but only if src has the
    > type char *. If not then I'll need the conversion.


    No. What you've written is an assignment statement, which has no effect
    whatsoever on the value of src. It only affects the value of the object
    that src points at. In this context, "*src" means "the object that src
    points at". To create a definition with an initializer for dst, it needs
    to start out as a declaration for dst:

    char *dst = &src;

    In the definition of dst, "*dst" does NOT mean "the object that dst
    points at". Rather, the * is part of "char *", which defines the type of
    dst. Also, the "=" that appears in this definition is part of the
    initialization syntax; it doesn't have the same meaning that it would
    have in an assignment statement. A definition with an initializer is
    just a shorthand for a declaration followed by an assignment statement:

    char *dst;
    dst = &src;

    Notice the absence of a '*' in the assignment statement. Please also
    note that neither the initializer nor the assignment statement would be
    valid unless src has the type 'char'. If src had type char*, as you
    suggest, then &src would have type char**, which it not permitted as an
    initializer for dst.
     
    James Kuyper, Oct 17, 2008
    #4
  5. tfelb

    Michael Guest

    tfelb wrote:
    > Hey group!
    >
    > I have 2 questions. I saw functions with char *dst = (char *)src. In
    > that case if I remember what I've learned I assign (an) (the) address
    > of src to dst. Right?
    >
    > But I can assign an address with the address operator & too? char *dst
    > = &src.
    >
    > What's the difference between *dst = (char *)src and *dst = &src and
    > what's the recommended style?
    >
    > 2. The same thing with returning a pointer from a function. If i write
    > a version of strchr i can return a pointer like
    >
    > return ptr OR
    > return (char *)ptr.
    >
    > I would think in both cases I'll return a pointer(address)
    >
    > Thanks for any help
    >
    > Tom
    >
    >
    >


    What is the declaration of dst and src?
     
    Michael, Oct 17, 2008
    #5
  6. tfelb

    Chris Dollin Guest

    James Kuyper wrote:

    > char *dst = &src;
    >
    > In the definition of dst, "*dst" does NOT mean "the object that dst
    > points at". Rather, the * is part of "char *", which defines the type of
    > dst. Also, the "=" that appears in this definition is part of the
    > initialization syntax; it doesn't have the same meaning that it would
    > have in an assignment statement. A definition with an initializer is
    > just a shorthand for a declaration followed by an assignment statement:
    >
    > char *dst;
    > dst = &src;


    Nitpick or not ?-- there are two ways I can think of that this isn't true.

    (a) consider `const int spoo = 17;`, which isn't usefully replaced by
    `const int spoo; spoo = 17;` since the assignment violates a
    constraint.

    (b) consider `int flarn = 42;` outside a function, where the assignment
    statement `flarn = 42;` isn't allowed even though assignments to
    `flarn` are permitted.

    --
    'Don't be afraid: /Electra City/
    there will be minimal destruction.' - Panic Room

    Hewlett-Packard Limited Cain Road, Bracknell, registered no:
    registered office: Berks RG12 1HN 690597 England
     
    Chris Dollin, Oct 17, 2008
    #6
  7. tfelb

    James Kuyper Guest

    Chris Dollin wrote:
    > James Kuyper wrote:

    ....
    >> have in an assignment statement. A definition with an initializer is
    >> just a shorthand for a declaration followed by an assignment statement:
    >>
    >> char *dst;
    >> dst = &src;

    >
    > Nitpick or not ?-- there are two ways I can think of that this isn't true.
    >
    > (a) consider `const int spoo = 17;`, which isn't usefully replaced by
    > `const int spoo; spoo = 17;` since the assignment violates a
    > constraint.
    >
    > (b) consider `int flarn = 42;` outside a function, where the assignment
    > statement `flarn = 42;` isn't allowed even though assignments to
    > `flarn` are permitted.


    That's perfectly true; and I thought about discussing those
    complications, but decided that he wasn't ready for them yet.
     
    James Kuyper, Oct 17, 2008
    #7
  8. Eric Sosman <> writes:
    > tfelb wrote:
    >> Hey group!
    >> I have 2 questions. I saw functions with char *dst = (char *)src. In
    >> that case if I remember what I've learned I assign (an) (the) address
    >> of src to dst. Right?


    [...]

    > Here's an important thing to keep in mind: A C pointer
    > is not merely an address, it's an address *and* a type.
    > If I hand you a naked address that might be represented on
    > some machine by the value 0x12345678 and ask you what value
    > is stored at that memory location, you do not have enough
    > information to answer me. Am I asking about the char at
    > that location, or about the int, or the double, or the
    > struct tm, or the what? You need to know what kind of a
    > value I'm asking about in order to know how many bytes to
    > examine and what significance to attach to them. In C, a
    > pointer's declared type carries this additional information;
    > the address alone is not enough.


    Correct -- *if* you're using the term "address" to mean a raw machine
    address. But in fact the C standard uses the term "address" to mean,
    basically, a pointer value. For example, given the declaration
    "int n;", the expression "&n" yields *the address of* n; that
    "address" includes both the location in the machine's memory and the
    fact that it's the address of an object of type int. (The latter
    information is part of the expression's type; it needn't actually be
    stored.)

    --
    Keith Thompson (The_Other_Keith) <http://www.ghoti.net/~kst>
    Nokia
    "We must do something. This is something. Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"
     
    Keith Thompson, Oct 17, 2008
    #8
  9. On Fri, 17 Oct 2008 04:34:48 -0700 (PDT), tfelb <>
    wrote:

    >Hey group!
    >
    >I have 2 questions. I saw functions with char *dst = (char *)src. In
    >that case if I remember what I've learned I assign (an) (the) address
    >of src to dst. Right?


    Only in a special case. It would always be true if the code was
    char *dst = (char *)&src;
    Note the added '&'.

    For this code:

    If src is an array, before the cast operator is applied the
    expression src is converted to the address of the first element of the
    array with type pointer to element type. Then your statement is true.

    If src is a scalar object, the value contained in the object
    (variable) src is converted to a char* value. (If src is an object
    pointer the conversion is well defined. If it is an integer object,
    it is implementation defined. I don't think it is defined for other
    types such as function pointer or non-array aggregates.) This
    converted value is stored in the char* named dst.

    >
    >But I can assign an address with the address operator & too? char *dst
    >= &src.


    Only if src is an object of type char.

    >
    >What's the difference between *dst = (char *)src and *dst = &src and
    >what's the recommended style?


    First, what you have written is different here. Your previous code
    contained object definitions. This code contains executable
    statements. I am going to assume you intended to continue in the same
    vein and there is an invisible "char" in front of both expressions.

    When src is a scalar object, the first expression works on the value
    contained in src while the second works on the address of src itself.

    If src is not an object of type char, the second is a constraint
    violation requiring a diagnostic. While any address can be converted
    to a char*, only the address of a char can be done so without a cast.

    >
    >2. The same thing with returning a pointer from a function. If i write
    >a version of strchr i can return a pointer like
    >
    >return ptr OR
    >return (char *)ptr.
    >
    >I would think in both cases I'll return a pointer(address)


    There is no type pointer. There are types pointer to char, pointer to
    int, etc. If your function is defined as returning a char*, then the
    value of ptr is returned AS IF BY ASSIGNMENT. This means the
    restrictions mentioned above apply. If ptr has type char*, the two
    return statements are obviously equivalent. If ptr is a different
    type of pointer, then only the second is legal.

    --
    Remove del for email
     
    Barry Schwarz, Oct 17, 2008
    #9
  10. tfelb

    tfelb Guest

    On 17 Okt., 16:52, Keith Thompson <> wrote:
    > Eric Sosman <> writes:
    > > tfelb wrote:
    > >> Hey group!
    > >> I have 2 questions. I saw  functions with char *dst = (char *)src. In
    > >> that case if I remember what I've learned I assign (an) (the) address
    > >> of src to dst. Right?

    >
    > [...]
    >
    > >     Here's an important thing to keep in mind: A C pointer
    > > is not merely an address, it's an address *and* a type.
    > > If I hand you a naked address that might be represented on
    > > some machine by the value 0x12345678 and ask you what value
    > > is stored at that memory location, you do not have enough
    > > information to answer me.  Am I asking about the char at
    > > that location, or about the int, or the double, or the
    > > struct tm, or the what?  You need to know what kind of a
    > > value I'm asking about in order to know how many bytes to
    > > examine and what significance to attach to them.  In C, a
    > > pointer's declared type carries this additional information;
    > > the address alone is not enough.

    >
    > Correct -- *if* you're using the term "address" to mean a raw machine
    > address.  But in fact the C standard uses the term "address" to mean,
    > basically, a pointer value.  For example, given the declaration
    > "int n;", the expression "&n" yields *the address of* n; that
    > "address" includes both the location in the machine's memory and the
    > fact that it's the address of an object of type int.  (The latter
    > information is part of the expression's type; it needn't actually be
    > stored.)
    >
    > --
    > Keith Thompson (The_Other_Keith)  <http://www.ghoti.net/~kst>
    > Nokia
    > "We must do something.  This is something.  Therefore, we must do this."
    >     -- Antony Jay and Jonathan Lynn, "Yes Minister"


    Ok. I'll think about these areas. Thank you all!
     
    tfelb, Oct 17, 2008
    #10
  11. tfelb wrote:
    > I have 2 questions. I saw functions with char *dst = (char *)src. In
    > that case if I remember what I've learned I assign (an) (the) address
    > of src to dst. Right?


    No. Assuming that 'src' is an object of pointer type, what is assigned
    to 'dst', is not the address of 'src', it is the _value_ stored in
    'src'. 'src' is a pointer, and the value stored in 'src' is an address
    of something 'src' points to (or possibly a null-pointer value). It is
    not the address of 'src' itself.

    > But I can assign an address with the address operator & too? char *dst
    > = &src.


    Yes. But in this case you get the address of 'src' itself.

    > What's the difference between *dst = (char *)src and *dst = &src


    See above.

    > and what's the recommended style?


    It is not a matter of style, since the two are not even remotely the same.

    Exception to the above: In one particular case when 'src' is an array,
    the apparent behavior might be identical in both assignments, due to
    certain specific properties of arrays in C. Since you didn't specify
    what 'src' is, it is impossible to say whether this is relevant to your
    question, the way you intended it.

    > 2. The same thing with returning a pointer from a function. If i write
    > a version of strchr i can return a pointer like
    >
    > return ptr OR
    > return (char *)ptr.


    The same? I don't see anything even remotely the same in this case. In
    your previous question you used the '&' operator. There's no '&' in this
    question, which makes is a completely different issue.

    > I would think in both cases I'll return a pointer(address)


    You you do return the value of 'ptr'. In the first case you don't cast
    it. In the second case you do. Without context it is impossibel to say
    whether you need the cast or not and what's the effect of the case.
    Clarify your question. Otherwise, it makes no sense.

    --
    Best regards,
    Andrey Tarasevich
     
    Andrey Tarasevich, Oct 17, 2008
    #11
  12. tfelb

    tfelb Guest

    On 17 Okt., 19:34, Andrey Tarasevich <>
    wrote:
    > tfelbwrote:
    > > I have 2 questions. I saw  functions with char *dst = (char *)src. In
    > > that case if I remember what I've learned I assign (an) (the) address
    > > of src to dst. Right?

    >
    > No. Assuming that 'src' is an object of pointer type, what is assigned
    > to 'dst', is not the address of 'src', it is the _value_ stored in
    > 'src'. 'src' is a pointer, and the value stored in 'src' is an address
    > of something 'src' points to (or possibly a null-pointer value). It is
    > not the address of 'src' itself.
    >
    > > But I can assign an address with the address operator & too? char *dst
    > > = &src.

    >
    > Yes. But in this case you get the address of 'src' itself.
    >
    > > What's the difference between *dst = (char *)src and *dst = &src

    >
    > See above.
    >
    > > and what's the recommended style?

    >
    > It is not a matter of style, since the two are not even remotely the same..
    >
    > Exception to the above: In one particular case when 'src' is an array,
    > the apparent behavior might be identical in both assignments, due to
    > certain specific properties of arrays in C. Since you didn't specify
    > what 'src' is, it is impossible to say whether this is relevant to your
    > question, the way you intended it.
    >
    >
    >
    > > 2. The same thing with returning a pointer from a function. If i write
    > > a version of strchr i can return a pointer like

    >
    > > return ptr OR
    > > return (char *)ptr.

    >
    > The same? I don't see anything even remotely the same in this case. In
    > your previous question you used the '&' operator. There's no '&' in this
    > question, which makes is a completely different issue.
    >
    > > I would think in both cases I'll return a pointer(address)

    >
    > You you do return the value of 'ptr'. In the first case you don't cast
    > it. In the second case you do. Without context it is impossibel to say
    > whether you need the cast or not and what's the effect of the case.
    > Clarify your question. Otherwise, it makes no sense.
    >
    > --
    > Best regards,
    > Andrey Tarasevich


    Ah hmm so for example if I have

    int num;

    and the address of num is 100 then the compiler would treat that
    variable internally as (int *)100 so
    an address &num == (int *)100.

    So the compiler see the statement int num = 3; as *(int *)100 = 3
    right?

    But why I need a pointer type and not for example (int)100 or unsigned
    int(100)?

    Thank you!

    Tom F.
     
    tfelb, Dec 9, 2008
    #12
  13. tfelb

    Chris Dollin Guest

    tfelb wrote:

    > Ah hmm so for example if I have
    >
    > int num;
    >
    > and the address of num is 100 then the compiler would treat that
    > variable internally as (int *)100 so
    > an address &num == (int *)100.


    Speaking generally, no.

    Most /compilers/ don't know the actual addresses of /any/ variables;
    in particular, automatic variables typically don't get allocated
    until the function they are in is entered, and when that happens is
    not under compiler control.

    Even static variables need not have a known address, just a way
    of referring to them in the generated code.

    And while `(int *) 100` may often give you the pointer value
    naturally corresponding to the 100'th position in your running
    programs store, /it is not required to/.

    > So the compiler see the statement int num = 3; as *(int *)100 = 3
    > right?


    Wrong.

    It sees it as `int num = 3;` or some internal representation of
    that. At various stages it might look like:

    <define num <bit int> <init <lit <bit int> 3>>>

    (A syntax tree, where <bit T> is "built-in type" and <lit T K>
    is "literal of type T and value K".)

    <stalloc num <bit int> <mode sp N>>
    <store <int 3> num>

    (Two virtual instructions, one allocation an int-sized slot
    at stack location N, the other storing an integer there.)

    <store <int 3> <sp N>>

    (One store instruction resulting from folding the allocated
    address for num into the code.)

    0x01020207

    (01 - store byte literal, 02 - as 32 bit integer on stack,
    the second 02 - the literal in question, 07 - the stack
    offset.)

    [I made the instruction up, but it's not that unlike instructions
    for actual machines.]

    > But why I need a pointer type and not for example (int)100 or
    > unsigned int(100)?


    You need a pointer type for pointers. Those two expressions are
    not pointer values.

    [1] 2, not 3, because the processor encodes the values 1-8 as
    0-7, because if you wanted to store 0 you'd use the `clear`
    instruction, wouldn't you.

    --
    "There's no 'we' in 'team'." Unsaid

    Hewlett-Packard Limited registered office: Cain Road, Bracknell,
    registered no: 690597 England Berks RG12 1HN
     
    Chris Dollin, Dec 9, 2008
    #13
    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. Replies:
    10
    Views:
    744
    Chris Torek
    Feb 4, 2005
  2. jimjim
    Replies:
    16
    Views:
    876
    Jordan Abel
    Mar 28, 2006
  3. Replies:
    4
    Views:
    1,330
    Fred Zwarts
    Jul 2, 2009
  4. A
    Replies:
    7
    Views:
    658
  5. , India

    pointer to an array vs pointer to pointer

    , India, Sep 20, 2011, in forum: C Programming
    Replies:
    5
    Views:
    499
    James Kuyper
    Sep 23, 2011
Loading...

Share This Page