difference between pointers

Discussion in 'C Programming' started by Varun Tewari, Mar 30, 2013.

  1. Varun Tewari

    Varun Tewari Guest

    hello all,

    I get this doubt about this behavior of C.

    consider the following code.

    int a,b,d1,d2,diff;

    d1= &a;
    d2 = &b;
    diff = &a-&b;
    printf("\nDifference between address: %d", diff);
    diff = d1-d2;
    printf("\nDifference between address(stored in integers): %d", diff);

    ideally, both printf should result same output.
    but as expected diff = d1-d2 gives 4.
    but diff = &a-&b gives 1.

    Why so when C doesn't really support operator overloading.
    Varun Tewari, Mar 30, 2013
    #1
    1. Advertising

  2. Varun Tewari

    Eric Sosman Guest

    On 3/30/2013 11:36 AM, Varun Tewari wrote:
    > hello all,
    >
    > I get this doubt about this behavior of C.
    >
    > consider the following code.
    >
    > int a,b,d1,d2,diff;
    >
    > d1= &a;
    > d2 = &b;
    > diff = &a-&b;
    > printf("\nDifference between address: %d", diff);
    > diff = d1-d2;
    > printf("\nDifference between address(stored in integers): %d", diff);
    >
    > ideally, both printf should result same output.
    > but as expected diff = d1-d2 gives 4.
    > but diff = &a-&b gives 1.
    >
    > Why so when C doesn't really support operator overloading.


    The short (and technical, and not very helpful) answer is
    that the code's behavior is undefined: The C language doesn't
    specify what should happen, so *anything* might happen.

    A longer answer ...

    First, pointer arithmetic always operates in units of the
    pointed-at type. Adding 1 to an `int*' advances the pointer
    to the next `int', adding 1 to a `double*' advances to the next
    `double', and so on. Even if an `int' occupies four bytes and
    a `double' occupies eight, adding 1 advances the pointer by the
    proper distance for its type.

    ... so subtraction works the same way: If you start with an
    `int*', add 1 to produce another pointer to the next `int', and
    then subtract the two values, what do you get? You get 1: the
    distance between the two objects is expressed in multiples of
    the object size. If you start with a pointer `p' and derive a
    new pointer `q' by computing `q = p + 3', it should come as no
    surprise that `q - p' yields 3.

    However, this adding and subtracting only works when you're
    navigating within in an array that contains the pointed-at objects.
    That's the only way to be sure of the right adjacency and spacing
    that allows pointer arithmetic to be defined. Consider: If you
    have two objects that are six bytes long, and if they exist at
    addresses eight bytes apart, the distance between them is not a
    multiple of the size and pointer arithmetic falls down: You can't
    add 1 to a pointer and have it advance by one-and-a-third objects!

    ... and that's where the undefined behavior enters your code.
    Since `a' and `b' are free-standing objects, unrelated to each
    other and not part of the same array, subtracting pointers to them
    cannot be guaranteed to produce a sensible answer. So C does not
    promise that anything sensible will happen; C says "the behavior
    is undefined" and just leaves it at that. In your case it seems
    that `a' and `b' did in fact wind up in adjacent memory regions,
    but that's a coincidence, not something C promises nor that you
    can rely on.

    Next topic: Why 1 vs. 4?

    C promises that a pointer can be converted to some kind of
    integer, but says very little about how wide an integer is needed
    and says nothing at all about the nature of the conversion. You
    take a pointer, convert it to an `int', and you get some kind of
    value. (It is not even guaranteed that you'll get the same value
    every time!) In your case, it seems that the address part of your
    pointer (or part of it) simply got transliterated into a bag of
    bits that were then interpreted as an `int' value -- that's a very
    common scheme, but not the only one.

    But notice what's left behind: The pointer "knew" what kind
    of object it pointed to, and hence the size of that object, and
    thus knew how to compensate for that size when doing arithmetic.
    The `int' resulting from conversion, though, has no information
    about the type of object the pointer aimed at, and cannot make
    adjustments for object size. So when you subtract the integers
    there's no adjustment: You get the distance between the objects
    expressed not in object-units, but in bytes (again, this is a
    common outcome but not the only possibility).

    Pointers are not "just addresses," but "addresses with type."

    --
    Eric Sosman
    d
    Eric Sosman, Mar 30, 2013
    #2
    1. Advertising

  3. Varun Tewari

    Tim Rentsch Guest

    Varun Tewari <> writes:

    > hello all,
    >
    > I get this doubt about this behavior of C.
    >
    > consider the following code.
    >
    > int a,b,d1,d2,diff;
    >
    > d1= &a;
    > d2 = &b;
    > diff = &a-&b;
    > printf("\nDifference between address: %d", diff);
    > diff = d1-d2;
    > printf("\nDifference between address(stored in integers): %d", diff);
    >
    > ideally, both printf should result same output.
    > but as expected diff = d1-d2 gives 4.
    > but diff = &a-&b gives 1.
    >
    > Why so when C doesn't really support operator overloading.


    Compiling this code should have produced at least one warning or
    error message. If it did not, you are very likely operating the
    compiler in a non-conforming mode; in other words, the language
    accepted may look a lot like C, but it isn't C.

    If the compiler you are using is gcc, try these options:

    gcc -ansi -pedantic-errors

    which directs gcc to operate according to how standard C is
    defined, rather than the "C-like but not C" language that
    gcc accepts by default.
    Tim Rentsch, Mar 30, 2013
    #3
  4. Varun Tewari

    Tim Rentsch Guest

    Eric Sosman <> writes:

    > On 3/30/2013 11:36 AM, Varun Tewari wrote:
    >> hello all,
    >>
    >> I get this doubt about this behavior of C.
    >>
    >> consider the following code.
    >>
    >> int a,b,d1,d2,diff;
    >>
    >> d1= &a;
    >> d2 = &b;
    >> diff = &a-&b;
    >> printf("\nDifference between address: %d", diff);
    >> diff = d1-d2;
    >> printf("\nDifference between address(stored in integers): %d", diff);
    >>
    >> ideally, both printf should result same output.
    >> but as expected diff = d1-d2 gives 4.
    >> but diff = &a-&b gives 1.
    >>
    >> Why so when C doesn't really support operator overloading.

    >
    > The short (and technical, and not very helpful) answer is
    > that the code's behavior is undefined: The C language doesn't
    > specify what should happen, so *anything* might happen.


    Except that, before getting to that point, a diagnostic is
    required -- assigning an integer to a pointer is a constraint
    violation.

    > [snip]
    >
    > C promises that a pointer can be converted to some kind of
    > integer, but says very little about how wide an integer is needed
    > and says nothing at all about the nature of the conversion. You
    > take a pointer, convert it to an `int', and you get some kind of
    > value. (It is not even guaranteed that you'll get the same value
    > every time!) In your case, it seems that the address part of your
    > pointer (or part of it) simply got transliterated into a bag of
    > bits that were then interpreted as an `int' value -- that's a very
    > common scheme, but not the only one.


    This is right in spirit but a lot of the details are wrong.

    C does promise that a pointer can be converted to one particular
    integer type; however, the conversion is completely specified,
    as is the width of the integer, because the type in question is
    the "boolean" type _Bool. The Standard does not guarantee that
    a pointer can be converted to any other integer type.

    If the header file <stdint.h> defines the types intptr_t,
    then these types are guaranteed to work for converting any valid
    pointer to void (ie, any valid pointer value of type 'void *');
    moreover, converting back the other direction is guaranteed to
    compare equal to the original pointer value.

    There is no guarantee that a pointer to any type other than
    void can be converted to any integer type other than _Bool. A
    pointer to void can be converted to the types intptr_t, but
    only if the implementation defines them, which the Standard
    does not require.

    On the flip side, the result of converting a pointer to an
    integer type is implementation-defined, which means each
    implementation has to document what it does. So, for any
    specific implementation, you can find out which integer types
    may be used to convert different kinds of pointer values, and
    what the result of those conversions will be.
    Tim Rentsch, Mar 30, 2013
    #4
  5. Eric Sosman <> writes:
    > On 3/30/2013 11:36 AM, Varun Tewari wrote:
    >> I get this doubt about this behavior of C.
    >>
    >> consider the following code.
    >>
    >> int a,b,d1,d2,diff;
    >>
    >> d1= &a;
    >> d2 = &b;
    >> diff = &a-&b;
    >> printf("\nDifference between address: %d", diff);
    >> diff = d1-d2;
    >> printf("\nDifference between address(stored in integers): %d", diff);

    [SNIP]
    > Next topic: Why 1 vs. 4?
    >
    > C promises that a pointer can be converted to some kind of
    > integer, but says very little about how wide an integer is needed
    > and says nothing at all about the nature of the conversion. You
    > take a pointer, convert it to an `int', and you get some kind of
    > value. (It is not even guaranteed that you'll get the same value
    > every time!) In your case, it seems that the address part of your
    > pointer (or part of it) simply got transliterated into a bag of
    > bits that were then interpreted as an `int' value -- that's a very
    > common scheme, but not the only one.


    You're assuming that this:

    d1 = &a; /* where d1 and a are both of type int */

    specifies a conversion. Nothing in the C standard says or implies
    that. The types int and int* are not assignment-compatible, so
    the assignment is a constraint violation, requiring a diagnostic.
    *If* the compiler chooses to generate an executable after issuing
    the diagnostic, nothing in the C standard says anything about how
    it behaves.

    It happens that, in most implementations, the behavior is equivalent
    to:

    d1 = (int)&a;

    for historical reasons. But you shouldn't depend on that; a
    conforming implementation could do *anything*. Don't waste your
    time running the program, just fix the source code.

    And in this case, the best fix is almost certainly *not* to add
    the cast (adding casts to silence warnings is rarely a good idea),
    but to change the declaration of d1.

    (I'm leaving aside the fact that the behavior of `&a - &b` is
    undefined; others have covered that.)

    [...]

    --
    Keith Thompson (The_Other_Keith) <http://www.ghoti.net/~kst>
    Working, but not speaking, for JetHead Development, Inc.
    "We must do something. This is something. Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"
    Keith Thompson, Mar 30, 2013
    #5
  6. Varun Tewari

    BartC Guest

    "Varun Tewari" <> wrote in message
    news:...
    > hello all,
    >
    > I get this doubt about this behavior of C.
    >
    > consider the following code.
    >
    > int a,b,d1,d2,diff;
    >
    > d1= &a;
    > d2 = &b;
    > diff = &a-&b;
    > printf("\nDifference between address: %d", diff);
    > diff = d1-d2;
    > printf("\nDifference between address(stored in integers): %d", diff);
    >
    > ideally, both printf should result same output.
    > but as expected diff = d1-d2 gives 4.
    > but diff = &a-&b gives 1.
    >
    > Why so when C doesn't really support operator overloading.


    I don't understand what overloading has to do with it.

    C likes to do pointer arithmetic in terms of 'objects' rather than bytes.
    &a-&b gives the difference in number of objects (and a, b happen to be next
    to each in memory, so one object difference).

    While d1-d2 subtracts one byte address from another, after each is converted
    to a plain int so that it no longer knows what kinds of pointers they were.

    It would be a little more interesting if a and b weren't aligned on a 4-byte
    boundary, and the byte-difference in their addresses wasn't a multiple of 4.
    (For this sort of reason, I'd have preferred pointer arithmetic to work in
    bytes, or rather chars, but using objects has its advantages too.)

    --
    Bartc
    BartC, Mar 30, 2013
    #6
  7. Varun Tewari

    Tim Rentsch Guest

    Keith Thompson <> writes:

    > Eric Sosman <> writes:
    >> On 3/30/2013 11:36 AM, Varun Tewari wrote:
    >>> I get this doubt about this behavior of C.
    >>>
    >>> consider the following code.
    >>>
    >>> int a,b,d1,d2,diff;
    >>>
    >>> d1= &a;
    >>> d2 = &b;
    >>> diff = &a-&b;
    >>> printf("\nDifference between address: %d", diff);
    >>> diff = d1-d2;
    >>> printf("\nDifference between address(stored in integers): %d", diff);

    > [SNIP]
    >> Next topic: Why 1 vs. 4?
    >>
    >> C promises that a pointer can be converted to some kind of
    >> integer, but says very little about how wide an integer is needed
    >> and says nothing at all about the nature of the conversion. You
    >> take a pointer, convert it to an `int', and you get some kind of
    >> value. (It is not even guaranteed that you'll get the same value
    >> every time!) In your case, it seems that the address part of your
    >> pointer (or part of it) simply got transliterated into a bag of
    >> bits that were then interpreted as an `int' value -- that's a very
    >> common scheme, but not the only one.

    >
    > You're assuming that this:
    >
    > d1 = &a; /* where d1 and a are both of type int */
    >
    > specifies a conversion. Nothing in the C standard says or implies
    > that. The types int and int* are not assignment-compatible, so
    > the assignment is a constraint violation, requiring a diagnostic.
    > *If* the compiler chooses to generate an executable after issuing
    > the diagnostic, nothing in the C standard says anything about how
    > it behaves. [...] a conforming implementation could do *anything*.
    > [snip elaboration]


    I'm not sure what your reasoning is to reach this conclusion.
    Certainly this assignment has a constraint violation, but you're
    saying, in effect, that it has undefined behavior. Presumably
    the underlying reasoning is one of two things, namely:

    A. There is a constraint violation, and any constraint
    violation is necessarily undefined behavior; or

    B. The assignment statement is trying to assign a pointer
    type to an integer type, and nothing in the Standard
    says how to do that, so there is undefined behavior.

    IMO point A is incorrect, although I would agree the point
    is debatable. Section 4 paragraph 3 says in part:

    If a ``shall'' or ``shall not'' requirement that appears
    outside of a constraint or runtime-constraint is violated,
    the behavior is undefined.

    This statement makes it reasonable to infer that a constraint
    violation might _not_ result in undefined behavior in some
    instances, as otherwise there is no point in excluding it.
    ("The exception proves the rule in cases not excepted.")

    Turning to point B, I think it is clearly just wrong, because
    of 6.5.16.1 p 2.

    Aside from the constraint violation, I don't see anything that
    makes this assignment have undefined behavior. If it is true
    that a constraint violation is not /ipso facto/ undefined
    behavior, then the behavior of this assignment is well-defined.
    A compiler is free to reject it (with the necessary diagnostic)
    because of the constraint violation; but if the compiler chooses
    to accept it, then the assignment must behave the same way that

    d1 = (int) &a;

    would.
    Tim Rentsch, Mar 30, 2013
    #7
  8. Varun Tewari

    Varun Tewari Guest

    Yep it did give warning.Thnx for pointing the correct gcc option for correct ansi parsing.
    Varun Tewari, Mar 31, 2013
    #8
  9. Tim Rentsch <> writes:
    > Keith Thompson <> writes:

    [...]
    >> You're assuming that this:
    >>
    >> d1 = &a; /* where d1 and a are both of type int */
    >>
    >> specifies a conversion. Nothing in the C standard says or implies
    >> that. The types int and int* are not assignment-compatible, so
    >> the assignment is a constraint violation, requiring a diagnostic.
    >> *If* the compiler chooses to generate an executable after issuing
    >> the diagnostic, nothing in the C standard says anything about how
    >> it behaves. [...] a conforming implementation could do *anything*.
    >> [snip elaboration]

    >
    > I'm not sure what your reasoning is to reach this conclusion.
    > Certainly this assignment has a constraint violation, but you're
    > saying, in effect, that it has undefined behavior. Presumably
    > the underlying reasoning is one of two things, namely:
    >
    > A. There is a constraint violation, and any constraint
    > violation is necessarily undefined behavior; or
    >
    > B. The assignment statement is trying to assign a pointer
    > type to an integer type, and nothing in the Standard
    > says how to do that, so there is undefined behavior.
    >
    > IMO point A is incorrect, although I would agree the point
    > is debatable. Section 4 paragraph 3 says in part:
    >
    > If a ``shall'' or ``shall not'' requirement that appears
    > outside of a constraint or runtime-constraint is violated,
    > the behavior is undefined.


    IMHO A is correct (programs with constraint violations have undefined
    behavior), though I'm not sure I can prove it.

    > This statement makes it reasonable to infer that a constraint
    > violation might _not_ result in undefined behavior in some
    > instances, as otherwise there is no point in excluding it.
    > ("The exception proves the rule in cases not excepted.")


    Perhaps, but only if the behavior is actually defined somewhere.

    > Turning to point B, I think it is clearly just wrong, because
    > of 6.5.16.1 p 2.


    Which says:

    In *simple assignment* (=), the value of the right operand is
    converted to the type of the assignment expression and replaces the
    value stored in the object designated by the left operand.

    That's an interesting point, but consider the definition of "constraint"
    in 3.8:

    restriction, either syntactic or semantic, by which the exposition
    of language elements is to be interpreted

    So the statement about the semantics of a simplea ssignment "is to
    be interpreted" in the context of the restriction on the operands.
    My conclusion from that is that if the constraint is violated,
    the statement doesn't apply.

    If the constraint is violated, it isn't a simple assignment.
    We don't know what it is, but it's not part of a valid C program.

    A compiler is free to reject a program containing such an assignment.
    If it does so, the conversion described in 6.5.16.1p2 does not
    occur -- but that doesn't mean the compiler is non-conforming.

    I suppose you could (and apparently do) interpret it to mean that
    the conversion occurs *if* the program is not rejected. I find
    that interpretation a bit strained.

    > Aside from the constraint violation, I don't see anything that
    > makes this assignment have undefined behavior. If it is true
    > that a constraint violation is not /ipso facto/ undefined
    > behavior, then the behavior of this assignment is well-defined.
    > A compiler is free to reject it (with the necessary diagnostic)
    > because of the constraint violation; but if the compiler chooses
    > to accept it, then the assignment must behave the same way that
    >
    > d1 = (int) &a;
    >
    > would.


    I disagree.

    Note also that, quoting 4p6:

    A conforming implementation may have extensions [...] provided they
    do not alter the behavior of any strictly conforming program.

    which implies that such an extension *could* alter the behavior of a
    program containing such an assignment.

    (It could also imply that an extension could alter the behavior
    of printf("%d\n", INT_MAX), which I find a bit troubling. I'm not
    sure that strict conformance was the best criterion to use there.)

    --
    Keith Thompson (The_Other_Keith) <http://www.ghoti.net/~kst>
    Working, but not speaking, for JetHead Development, Inc.
    "We must do something. This is something. Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"
    Keith Thompson, Mar 31, 2013
    #9
  10. Varun Tewari

    Joe Pfeiffer Guest

    "christian.bau" <> writes:

    > On Mar 30, 3:36 pm, Varun Tewari <> wrote:
    >> hello all,
    >>
    >> I get this doubt about this behavior of C.

    >
    > You don't have a doubt, you have a question. A "doubt" is a "feeling
    > of uncertainty or lack of conviction".


    There are areas of the world in which "doubt" is used exactly as
    Americans and Europeans use "question". This was one of the things I
    had to get used to when I started having significant numbers of students
    from India.
    Joe Pfeiffer, Mar 31, 2013
    #10
  11. I have a doubt... (Was: difference between pointers)

    In article <>,
    Joe Pfeiffer <> wrote:
    >"christian.bau" <> writes:
    >
    >> On Mar 30, 3:36 pm, Varun Tewari <> wrote:
    >>> hello all,
    >>>
    >>> I get this doubt about this behavior of C.

    >>
    >> You don't have a doubt, you have a question. A "doubt" is a "feeling
    >> of uncertainty or lack of conviction".

    >
    >There are areas of the world in which "doubt" is used exactly as
    >Americans and Europeans use "question". This was one of the things I
    >had to get used to when I started having significant numbers of students
    >from India.


    Which leads inevitably to the ago-old question. Say you find yourself in a
    situation where, speaking on the topic of dogs, large numbers of people call
    a tail a "leg". Do you accept that as acceptable usage and go along with
    the crowd, or do you patiently instruct them, over and over, that a tail is
    not a leg?

    And note, given that in this newsgroup, people never get tired of bitching
    about "void main" or telling people not to cast the return value of malloc,
    or about how not #includ'ing stdio.h causes undefined behavior, I don't
    think there's much likelihood they'll stop bitching about people misusing
    the word "doubt".

    people not
    --
    A liberal, a moderate, and a conservative walk into a bar...

    Bartender says, "Hi, Mitt!"
    Kenny McCormack, Apr 1, 2013
    #11
  12. Varun Tewari

    Joe Pfeiffer Guest

    Re: I have a doubt...

    (Kenny McCormack) writes:

    > In article <>,
    > Joe Pfeiffer <> wrote:
    >>"christian.bau" <> writes:
    >>
    >>> On Mar 30, 3:36 pm, Varun Tewari <> wrote:
    >>>> hello all,
    >>>>
    >>>> I get this doubt about this behavior of C.
    >>>
    >>> You don't have a doubt, you have a question. A "doubt" is a "feeling
    >>> of uncertainty or lack of conviction".

    >>
    >>There are areas of the world in which "doubt" is used exactly as
    >>Americans and Europeans use "question". This was one of the things I
    >>had to get used to when I started having significant numbers of students
    >>from India.

    >
    > Which leads inevitably to the ago-old question. Say you find yourself in a
    > situation where, speaking on the topic of dogs, large numbers of people call
    > a tail a "leg". Do you accept that as acceptable usage and go along with
    > the crowd, or do you patiently instruct them, over and over, that a tail is
    > not a leg?
    >
    > And note, given that in this newsgroup, people never get tired of bitching
    > about "void main" or telling people not to cast the return value of malloc,
    > or about how not #includ'ing stdio.h causes undefined behavior, I don't
    > think there's much likelihood they'll stop bitching about people misusing
    > the word "doubt".


    Those are legitimate concerns about C.
    Joe Pfeiffer, Apr 1, 2013
    #12
  13. "BartC" <> writes:
    > "Varun Tewari" <> wrote in message
    > news:...
    >> I get this doubt about this behavior of C.
    >>
    >> consider the following code.
    >>
    >> int a,b,d1,d2,diff;
    >>
    >> d1= &a;
    >> d2 = &b;
    >> diff = &a-&b;
    >> printf("\nDifference between address: %d", diff);
    >> diff = d1-d2;
    >> printf("\nDifference between address(stored in integers): %d", diff);
    >>
    >> ideally, both printf should result same output.
    >> but as expected diff = d1-d2 gives 4.
    >> but diff = &a-&b gives 1.
    >>
    >> Why so when C doesn't really support operator overloading.

    >
    > I don't understand what overloading has to do with it.


    The "-" operator actually is overloaded: it can be applied to
    integers, floating-point values, or pointers. What C doesn't
    support is *user-defined* operator overloading.

    > C likes to do pointer arithmetic in terms of 'objects' rather than bytes.
    > &a-&b gives the difference in number of objects (and a, b happen to be next
    > to each in memory, so one object difference).
    >
    > While d1-d2 subtracts one byte address from another, after each is converted
    > to a plain int so that it no longer knows what kinds of pointers they were.
    >
    > It would be a little more interesting if a and b weren't aligned on a 4-byte
    > boundary, and the byte-difference in their addresses wasn't a multiple of 4.
    > (For this sort of reason, I'd have preferred pointer arithmetic to work in
    > bytes, or rather chars, but using objects has its advantages too.)


    The main purpose of pointer arithmetic is to access elements within
    arrays. For example, the indexing operator [] is defined in terms
    of pointer arithmetic. The distance between elements of an array
    is always a whole multiple of the size of each element.

    If you want the difference *in bytes* between two pointer values,
    you can just convert both pointers to char*.

    Yes, pointer arithmetic could have been defined in terms of bytes, but
    it's more convenient the way it is.

    --
    Keith Thompson (The_Other_Keith) <http://www.ghoti.net/~kst>
    Working, but not speaking, for JetHead Development, Inc.
    "We must do something. This is something. Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"
    Keith Thompson, Apr 1, 2013
    #13
  14. Re: I have a doubt... (Was: difference between pointers)

    (Kenny McCormack) writes:

    [ ... ]
    > Which leads inevitably to the ago-old question. Say you find yourself in a
    > situation where, speaking on the topic of dogs, large numbers of people call
    > a tail a "leg". Do you accept that as acceptable usage and go along with
    > the crowd, or do you patiently instruct them, over and over, that a tail is
    > not a leg?


    Or perhaps: Say you find yourself in a situation where, speaking on
    the topic of "hunds", large numbers of people call a "shank" a "leg".
    Do you accept that as acceptable usage and go along with the crowd, or
    do you patiently instruct them, over and over, that a leg is not a
    shank? And when you've given up on that someone starts to call a
    "hund" a "dog", and here we go again.

    --
    ... Øyvind - soon to appear in a kill file near you.
    ... Ignorance can be cured; stupidity is forever.
    Øyvind Røtvold, Apr 1, 2013
    #14
  15. Re: I have a doubt... (Was: difference between pointers)

    In article <>,
    Øyvind Røtvold <> wrote:
    >
    > (Kenny McCormack) writes:
    >
    >[ ... ]
    >> Which leads inevitably to the ago-old question. Say you find yourself in a
    >> situation where, speaking on the topic of dogs, large numbers of people call
    >> a tail a "leg". Do you accept that as acceptable usage and go along with
    >> the crowd, or do you patiently instruct them, over and over, that a tail is
    >> not a leg?

    >
    >Or perhaps: Say you find yourself in a situation where, speaking on
    >the topic of "hunds", large numbers of people call a "shank" a "leg".
    >Do you accept that as acceptable usage and go along with the crowd, or
    >do you patiently instruct them, over and over, that a leg is not a
    >shank? And when you've given up on that someone starts to call a
    >"hund" a "dog", and here we go again.


    Or you could just say "To heck with it all" and go back to bitching about
    void main() and casting the return value of malloc().

    --
    Modern Christian: Someone who can take time out from
    complaining about "welfare mothers popping out babies we
    have to feed" to complain about welfare mothers getting
    abortions that PREVENT more babies to be raised at public
    expense.
    Kenny McCormack, Apr 1, 2013
    #15
  16. Varun Tewari

    Varun Tewari Guest

    Re: I have a doubt... (Was: difference between pointers)

    Thnx Everyone.

    For me my doubts are cleared, and for those who think it wasn't a doubt but a question, yes my questions are well answered.

    :)
    Varun Tewari, Apr 1, 2013
    #16
  17. Varun Tewari

    Tim Rentsch Guest

    Varun Tewari <> writes:

    > Yep it did give warning. Thnx for pointing the correct gcc option for
    > correct ansi parsing.


    You may also want to try

    gcc -std=c99 -pedantic-errors

    or (if you have a newer version of gcc)

    gcc -std=c11 -pedantic-errors

    instead of using -ansi, which specifies the 1990 version of ISO C.
    Tim Rentsch, Apr 2, 2013
    #17
  18. Varun Tewari

    Tim Rentsch Guest

    Keith Thompson <> writes:

    > Tim Rentsch <> writes:
    >> Keith Thompson <> writes:

    > [...]
    >>> You're assuming that this:
    >>>
    >>> d1 = &a; /* where d1 and a are both of type int */
    >>>
    >>> specifies a conversion. Nothing in the C standard says or implies
    >>> that. The types int and int* are not assignment-compatible, so
    >>> the assignment is a constraint violation, requiring a diagnostic.
    >>> *If* the compiler chooses to generate an executable after issuing
    >>> the diagnostic, nothing in the C standard says anything about how
    >>> it behaves. [...] a conforming implementation could do *anything*.
    >>> [snip elaboration]

    >>
    >> I'm not sure what your reasoning is to reach this conclusion.
    >> Certainly this assignment has a constraint violation, but you're
    >> saying, in effect, that it has undefined behavior. Presumably
    >> the underlying reasoning is one of two things, namely:
    >>
    >> A. There is a constraint violation, and any constraint
    >> violation is necessarily undefined behavior; or
    >>
    >> B. The assignment statement is trying to assign a pointer
    >> type to an integer type, and nothing in the Standard
    >> says how to do that, so there is undefined behavior.
    >>
    >> IMO point A is incorrect, although I would agree the point
    >> is debatable. Section 4 paragraph 3 says in part:
    >>
    >> If a ``shall'' or ``shall not'' requirement that appears
    >> outside of a constraint or runtime-constraint is violated,
    >> the behavior is undefined.

    >
    > IMHO A is correct (programs with constraint violations have
    > undefined behavior), though I'm not sure I can prove it.
    >
    >> This statement makes it reasonable to infer that a constraint
    >> violation might _not_ result in undefined behavior in some
    >> instances, as otherwise there is no point in excluding it.
    >> ("The exception proves the rule in cases not excepted.")

    >
    > Perhaps, but only if the behavior is actually defined somewhere.


    The behavior is defined by the semantics paragraphs of "Simple
    assignment", which the expression in question must have been
    identified as being. (This point expanded on below.)

    >> Turning to point B, I think it is clearly just wrong, because
    >> of 6.5.16.1 p 2.

    >
    > Which says:
    >
    > In *simple assignment* (=), the value of the right operand is
    > converted to the type of the assignment expression and
    > replaces the value stored in the object designated by the left
    > operand.
    >
    > That's an interesting point, but consider the definition of
    > "constraint" in 3.8:
    >
    > restriction, either syntactic or semantic, by which the exposition
    > of language elements is to be interpreted
    >
    > So the statement about the semantics of a simplea ssignment "is to
    > be interpreted" in the context of the restriction on the operands.
    > My conclusion from that is that if the constraint is violated,
    > the statement doesn't apply.
    >
    > If the constraint is violated, it isn't a simple assignment.
    > We don't know what it is, but it's not part of a valid C program.


    The problem with this reasoning is that the compiler must have
    identified the expression as a simple assignment, because the
    constraint only applies to simple assignments, and violating a
    constraint requires a diagnostic. If we don't know that the
    expression is a simple assignment, then there is no constraint
    violation, and the compiler would be free to treat the program as
    having undefined behavior, without issuing a diagnostic. This is
    a classic "you can't have it both ways" kind of situation. The
    only reasonable way out is to say the compiler must identify the
    expression in question as a simple assignment, and proceed
    accordingly.

    > A compiler is free to reject a program containing such an assignment.
    > If it does so, the conversion described in 6.5.16.1p2 does not
    > occur -- but that doesn't mean the compiler is non-conforming.


    I don't see what this has to do with anything. Obviouly a
    program that did not successfully compile (ie, was rejected)
    won't have any of its semantic actions carried out. There are a
    variety of reasons why a compiler might reject a program;
    rejecting it because it has a constraint violation isn't any
    different in this regard.

    > I suppose you could (and apparently do) interpret it to mean that
    > the conversion occurs *if* the program is not rejected. I find
    > that interpretation a bit strained.


    I don't see why. It seems reasonable that the semantics described
    under "Simple assignment" would apply; detabable maybe, but not
    unreasonable, certainly not a big stretch. And those semantics
    clearly spell out a particular well-defined behavior (and which
    includes the conversion).

    >> Aside from the constraint violation, I don't see anything that
    >> makes this assignment have undefined behavior. If it is true
    >> that a constraint violation is not /ipso facto/ undefined
    >> behavior, then the behavior of this assignment is well-defined.
    >> A compiler is free to reject it (with the necessary diagnostic)
    >> because of the constraint violation; but if the compiler chooses
    >> to accept it, then the assignment must behave the same way that
    >>
    >> d1 = (int) &a;
    >>
    >> would.

    >
    > I disagree.


    Let me point out that the final sentence is predicated on the 'If
    it is true that ...' condition given earlier in the paragraph.
    In this paragraph it is not my intention to make an absolute
    statement, only a relative one.

    To try to bring the conversation up a level: the essential point I
    was trying to make is that the question is not black and white.
    Reasonable people can disagree here. In the interest of giving a
    fair presentation under such circumstances, I think it's better to
    give a qualified statement rather than treating the matter as
    completely settled.

    > Note also that, quoting 4p6:
    >
    > A conforming implementation may have extensions [...] provided they
    > do not alter the behavior of any strictly conforming program.
    >
    > which implies that such an extension *could* alter the behavior of a
    > program containing such an assignment.
    >
    > (It could also imply that an extension could alter the behavior
    > of printf("%d\n", INT_MAX), which I find a bit troubling. I'm not
    > sure that strict conformance was the best criterion to use there.)


    The area of "extensions" is a little murky. Looking through the
    section on common extensions, it isn't clear just how much is
    allowed (at least one example seems to imply that an extension
    could change the meaning of a strictly conforming program).
    Certainly extensions have great latitude to re-define behavior,
    as your example illustrates, even if it isn't clear just how
    great that latitude is.

    However, regarding what is required for this kind of assignment
    expression, the matter of extensions can easily be rendered moot,
    because extensions are reguired to be documented. We can simply
    ask the question of what behavior is required for implementations
    that do not document any extensions in such cases.
    Tim Rentsch, Apr 2, 2013
    #18
  19. Varun Tewari

    army1987 Guest

    On Sat, 30 Mar 2013 11:13:50 -0700, Tim Rentsch wrote:

    > There is no guarantee that a pointer to any type other than void can be
    > converted to any integer type other than _Bool. A pointer to void can
    > be converted to the types intptr_t, but only if the implementation
    > defines them, which the Standard does not require.


    Is there any good reason why (intptr_t)&i isn't required to be the same
    as (intptr_t)(void *)&i? (Crossposted to comp.std.c.)

    --
    [ T H I S S P A C E I S F O R R E N T ]
    Troppo poca cultura ci rende ignoranti, troppa ci rende folli.
    -- fathermckenzie di it.cultura.linguistica.italiano
    <http://xkcd.com/397/>
    army1987, Apr 2, 2013
    #19
  20. Varun Tewari

    army1987 Guest

    Re: I have a doubt... (Was: difference between pointers)

    On Mon, 01 Apr 2013 00:10:22 +0000, Kenny McCormack wrote:

    > Which leads inevitably to the ago-old question. Say you find yourself
    > in a situation where, speaking on the topic of dogs, large numbers of
    > people call a tail a "leg". Do you accept that as acceptable usage and
    > go along with the crowd, or do you patiently instruct them, over and
    > over, that a tail is not a leg?
    >
    > And note, given that in this newsgroup, people never get tired of
    > bitching about "void main" or telling people not to cast the return
    > value of malloc, or about how not #includ'ing stdio.h causes undefined
    > behavior, I don't think there's much likelihood they'll stop bitching
    > about people misusing the word "doubt".


    The difference being that there's an ISO standard defining what "void main
    ()" means or doesn't mean, but there's no official standard defining what
    "doubt" means or doesn't mean; there are _de facto_ standards for that
    but they don't happen to agree with each other. (I think it's most
    useful to stick to one of the _de facto_ standards that are followed by a
    sizeable number of native English speakers and don't confuse people
    following different _de facto_ standards too much, and the particular _de
    facto_ standard according to which "doubt" can mean 'question' doesn't
    fulfil these criteria; but still.)



    --
    [ T H I S S P A C E I S F O R R E N T ]
    Troppo poca cultura ci rende ignoranti, troppa ci rende folli.
    -- fathermckenzie di it.cultura.linguistica.italiano
    <http://xkcd.com/397/>
    army1987, Apr 2, 2013
    #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. jakk
    Replies:
    4
    Views:
    12,139
  2. Me
    Replies:
    79
    Views:
    5,270
    Dan Pop
    Jun 18, 2004
  3. Replies:
    7
    Views:
    424
    Keith Thompson
    Oct 3, 2006
  4. ram kishore

    Difference between function pointers

    ram kishore, Jul 25, 2008, in forum: C Programming
    Replies:
    8
    Views:
    418
    Ben Bacarisse
    Jul 27, 2008
  5. cerr

    pointers, pointers, pointers...

    cerr, Apr 7, 2011, in forum: C Programming
    Replies:
    12
    Views:
    672
Loading...

Share This Page