Code problem

Discussion in 'C Programming' started by rage, Jun 8, 2012.

  1. rage

    rage Guest

    Can someone please help me out on this?

    #include<stdio.h>
    main()
    {
    int i;
    int *j=10;
    i=j+19;
    printf("%d %d\n",j,i);
    }

    The output is a garbage value (86) on my pc and ideone. Should it not be 29?
    rage, Jun 8, 2012
    #1
    1. Advertising

  2. rage

    Eric Sosman Guest

    On 6/8/2012 10:52 AM, rage wrote:
    > Can someone please help me out on this?
    >
    > #include<stdio.h>
    > main()
    > {
    > int i;
    > int *j=10;


    What are you trying to accomplish with this line? Your compiler
    should have given you a diagnostic message about it; what did the
    message say, and what meaning did you think it had?

    > i=j+19;


    Should have received another diagnostic message for this line.

    > printf("%d %d\n",j,i);


    No diagnostic is *required* for this line, but some compilers
    are smart and helpful enough to issue one.

    > }
    >
    > The output is a garbage value (86) on my pc and ideone. Should it not be 29?


    Your code's behavior is undefined, so there is no reason you
    "should" expect any particular output, nor even any output at all.
    What are you trying to do?

    --
    Eric Sosman
    d
    Eric Sosman, Jun 8, 2012
    #2
    1. Advertising

  3. rage

    Stefan Ram Guest

    rage <> writes:
    >The output is a garbage value (86) on my pc and ideone. Should it not be 29?


    Why did you write the asterisk?
    Stefan Ram, Jun 8, 2012
    #3
  4. rage

    Kaz Kylheku Guest

    On 2012-06-08, rage <> wrote:
    > Can someone please help me out on this?


    Your code is not a well-formed ISO C program. It contains type system
    violations that require a diagnostic.

    > #include<stdio.h>
    > main()
    > {
    > int i;
    > int *j=10;


    Here, a variable of pointer type is being initialized with an integer value.

    > i=j+19;


    Here, an integer object is being assigned from a pointer expression.

    > printf("%d %d\n",j,i);


    Here, the %d conversion specifier, which requires a matching argument of type
    int, is given an argument of type "int *". This is undefined behavior.

    > }
    >
    > The output is a garbage value (86) on my pc and ideone. Should it not be 29?


    Since the program requires diagnostics, the ISO C standard doesn't require the
    implementation to translate and execute the program. If the program translates
    and executes anyway, its behavior is not defined by ISO C. Of course, it has a
    behavior, but implementation-specific reasoning is required to understand it.

    For instance, whether or not you can print a pointer using %d will depend
    on the calling conventions, and that can be sensitive to different versions
    of even the same compiler. What if pointers are 64 bits wide but int is 32
    bits? In that case it is conceivable that "%d %d" will just take two halves
    of the 64 bit j value, and i is ignored.

    This kind of program is usually not correct even according to the local
    compiler and library documentation, never mind ISO C.
    Kaz Kylheku, Jun 8, 2012
    #4
  5. rage

    Angel Guest

    On 2012-06-08, rage <> wrote:
    > Can someone please help me out on this?
    >
    > #include<stdio.h>
    > main()
    > {
    > int i;
    > int *j=10;


    In this line, you're converting an integer value to a pointer. That
    is an operation with undefined behavior. (Except if the integer is a
    constant value of zero, if I recall right.)

    Because of this undefined behavior, your program may not compile at
    all. Even if it does, it may not run. Even if it runs, it may not give
    any sensible output. Undefined behavior basically means "sorry mate,
    you're on your own here".

    Do you actually know what pointers are? If not, I'd recommend not using
    the unary & and * operators until you do.


    --
    "C provides a programmer with more than enough rope to hang himself.
    C++ provides a firing squad, blindfold and last cigarette."
    - seen in comp.lang.c
    Angel, Jun 8, 2012
    #5
  6. rage

    James Kuyper Guest

    On 06/08/2012 10:52 AM, rage wrote:
    > Can someone please help me out on this?
    >
    > #include<stdio.h>
    > main()
    > {
    > int i;
    > int *j=10;


    You're trying to initializing j, which is a pointer to an int, with the
    value of 10, which is an integer. That's a constraint violation
    (6.5.16.1p1). A conforming implementation is required to issue a
    diagnostic message - did yours? If so, what did it say?

    After issuing the diagnostic, your compiler is free to do anything it
    wants with your code. I suspect that what it is doing is converting 10
    to a pointer value, and storing that pointer value in j.

    You could force it to do that conversion explicitly by inserting an
    (int*) before the 10, in which case the constraint violation would go
    away. However, the resulting pointer value is implementation-defined. It
    might contain a trap representation, in which case the behavior of your
    program would still be undefined. Even if it is not a trap
    representation, you have no idea where in memory it points at. It
    probably does not point at a piece of memory reserved for use by your
    program; if it does, there's a small chance it points at the same piece
    of memory reserved to store the value of 'i'.

    > i=j+19;


    Since you don't know what location in memory j points at, you can't be
    sure whether adding 19 to that pointer will have defined behavior; it
    probably doesn't.

    You're trying to store the result of that addition, which is a pointer
    value, into an int object. This is once again a constraint violation,
    with the same consequences as the first time.

    > printf("%d %d\n",j,i);


    You're using a %d format specifier, which should be used only for int
    values, to print the value of j, which is a pointer. That's yet another
    example of undefined behavior.

    > }
    >
    > The output is a garbage value (86) on my pc and ideone. Should it not be 29?


    The output could have been anything, including the text of the "Star
    Spangled Banner" (or nothing at all). That's what "undefined behavior"
    means.

    Here's correct code that does something similar to what your original
    code may have been meant to do:

    int i;
    int k;
    int *j=&k;
    *j = 10;
    i = *j+19;
    printf("%d %d\n", *j, i);
    James Kuyper, Jun 8, 2012
    #6
  7. rage

    BartC Guest

    "rage" <> wrote in message
    news:...
    > Can someone please help me out on this?
    >
    > #include<stdio.h>
    > main()
    > {
    > int i;
    > int *j=10;
    > i=j+19;
    > printf("%d %d\n",j,i);
    > }
    >
    > The output is a garbage value (86) on my pc and ideone. Should it not be
    > 29?


    Assuming you did intend j to be a pointer, try it like this:

    #include<stdio.h>
    #include<stdlib.h>

    int main(void)
    {
    int i;
    int *j=malloc(sizeof(int));
    *j=10;
    i=*j+19;
    printf("%d %d\n",*j,i);
    }

    (The code assumes the malloc() call is successful.)

    --
    Bartc
    BartC, Jun 8, 2012
    #7
  8. rage

    John Gordon Guest

    In <> rage <> writes:

    > Can someone please help me out on this?


    > #include<stdio.h>
    > main()
    > {
    > int i;
    > int *j=10;
    > i=j+19;
    > printf("%d %d\n",j,i);
    > }


    > The output is a garbage value (86) on my pc and ideone. Should it not be 29?


    You declared j as an integer pointer, and initialized it to point at memory
    location 10, which very likely contains an unknown value.

    As others have said, your compiler should have issued a warning about
    this, which would have given you a clue as to what the problem was.

    --
    John Gordon A is for Amy, who fell down the stairs
    B is for Basil, assaulted by bears
    -- Edward Gorey, "The Gashlycrumb Tinies"
    John Gordon, Jun 8, 2012
    #8
  9. rage

    Les Cargill Guest

    rage wrote:
    > Can someone please help me out on this?
    >
    > #include<stdio.h>
    > main()
    > {
    > int i;
    > int *j=10;
    > i=j+19;
    > printf("%d %d\n",j,i);
    > }
    >
    > The output is a garbage value (86) on my pc and ideone. Should it not be 29?
    >



    Your code is broken:

    int i;
    int k = 10;
    int *j = &k;
    i=(*j)+19;
    printf("%d %d\n",*j,i);

    might work as you expect. "int *j;" declares j as "a pointer
    to an integer". "j = 10;" make it point to address 10.

    you probably don't want that.

    From that point on, you're not in Kansas any more.. you're exposing...
    <puts on sunglasses>
    UNDEFINED BEHAVIOR!

    --
    Les Cargill
    Les Cargill, Jun 8, 2012
    #9
  10. Angel <> writes:
    > On 2012-06-08, rage <> wrote:
    >> Can someone please help me out on this?
    >>
    >> #include<stdio.h>
    >> main()
    >> {
    >> int i;
    >> int *j=10;

    >
    > In this line, you're converting an integer value to a pointer. That
    > is an operation with undefined behavior. (Except if the integer is a
    > constant value of zero, if I recall right.)


    What makes you think there's a conversion there?

    The declaration violates a constraint. An initialization has
    the same constraints as a simple assignment (N1570 6.7.9p11).
    The rules for simple assignment say that if the left hand side has
    pointer type, the right hand side must have pointer type (either
    a compatible type or void*) or it can be a null pointer constant.

    Since

    int *j = 10;

    doesn't satisfy these constraints, there is no definition of its
    behavior. In particular, the standard does not say or imply that the
    int value 10 should be converted to int*.

    That was the typical behavior for pre-standard versions of C, and
    most compilers that don't reject the declaration will generate code
    equivalent to:

    int *j = (int*)10;

    But it's not required.

    Note that the behavior of an integer-to-pointer conversion is not
    (entirely) undefined. N1570 6.3.2.3 says:

    An integer may be converted to any pointer type. Except as
    previously specified, the result is implementation-defined,
    might not be correctly aligned, might not point to an entity
    of the referenced type, and might be a trap representation.

    with a footnote:

    The mapping functions for converting a pointer to an integer
    or an integer to a pointer are intended to be consistent with
    the addressing structure of the execution environment.

    (But that's not relevant to this code because, as I said, no conversion
    is implied.)

    [...]

    --
    Keith Thompson (The_Other_Keith) <http://www.ghoti.net/~kst>
    Will write code for food.
    "We must do something. This is something. Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"
    Keith Thompson, Jun 8, 2012
    #10
  11. rage <> writes:
    > Can someone please help me out on this?
    >
    > #include<stdio.h>
    > main()
    > {
    > int i;
    > int *j=10;
    > i=j+19;
    > printf("%d %d\n",j,i);
    > }
    >
    > The output is a garbage value (86) on my pc and ideone. Should it not be 29?


    The value 86 is not garbage, though the program that produced it is.

    First off, "main()" should be "int main(void)". Most compilers will
    probably accept "main()", but it's an obsolete form.

    int *j = 10;

    is a constraint violation. Your compiler should have either produced a
    warning or rejected it outright, and you should have told us that. If
    your compiler doesn't produce a diagnostic, then it's misbehaving; find
    out how to invoke it so that it produces proper diagnostics.

    If it's not rejected, the most likely behavior is that the compiler will
    treat it as if you had written:

    int *j = (int*)10;

    which converts the int value 10 to int* and stores it in j. This is
    almost certainly a nonsensical thing to do, but it's legal; the result
    of the conversion is implementation-defined.

    i = j + 19;

    Since j is a pointer object, j + 19 performs pointer arithmetic. Given
    a pointer value p and an integer value n, the expression p + n assumes
    that p points to an element of an array and yields a pointer n elements
    past the one that p points to. In other words, pointer arithmetic is
    scaled by the size of the pointed-to type.

    If sizeof (int) == 4 on your system, then j + 19 is likely to yield a
    pointer to a location 76 bytes (19 int objects) past the location that j
    points to.

    printf("%d %d\n", j, i);

    This has undefined behavior. The "%d" format requires an int argument,
    but you're giving it an int*. But given a few plausible assumptions,
    such as that int and int* happen to have the same size and that
    conversions between pointers and integers just reinterpret the
    representation without performing any other transformation, it's likely
    that it will print

    10 89

    where 10 is the value of j (10 converted from int to int*, and the
    interpreted as if it were an int), and 89 is the value of i
    (10 + (4*19), but with several conversions from int to int* and
    back again).

    The only thing you really *need* to know about this program is that
    it's invalid. You have several instances of undefined behavior, and
    one constraint violation, requiring a compile-time diagnostic that
    *you should not ignore*. The above is a plausible explanation of
    the behavior you're seeing -- but it could be completely different
    on another system, or on the same system with different options,
    or it could be rejected altogether.

    --
    Keith Thompson (The_Other_Keith) <http://www.ghoti.net/~kst>
    Will write code for food.
    "We must do something. This is something. Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"
    Keith Thompson, Jun 8, 2012
    #11
  12. rage

    Angel Guest

    On 2012-06-08, Keith Thompson <> wrote:
    > Angel <> writes:
    >> On 2012-06-08, rage <> wrote:
    >>> Can someone please help me out on this?
    >>>
    >>> #include<stdio.h>
    >>> main()
    >>> {
    >>> int i;
    >>> int *j=10;

    >>
    >> In this line, you're converting an integer value to a pointer. That
    >> is an operation with undefined behavior. (Except if the integer is a
    >> constant value of zero, if I recall right.)

    >
    > What makes you think there's a conversion there?
    >
    > The declaration violates a constraint. An initialization has
    > the same constraints as a simple assignment (N1570 6.7.9p11).
    > The rules for simple assignment say that if the left hand side has
    > pointer type, the right hand side must have pointer type (either
    > a compatible type or void*) or it can be a null pointer constant.
    >
    > Since
    >
    > int *j = 10;
    >
    > doesn't satisfy these constraints, there is no definition of its
    > behavior. In particular, the standard does not say or imply that the
    > int value 10 should be converted to int*.
    >
    > That was the typical behavior for pre-standard versions of C, and
    > most compilers that don't reject the declaration will generate code
    > equivalent to:
    >
    > int *j = (int*)10;
    >
    > But it's not required.
    >
    > Note that the behavior of an integer-to-pointer conversion is not
    > (entirely) undefined. N1570 6.3.2.3 says:
    >
    > An integer may be converted to any pointer type. Except as
    > previously specified, the result is implementation-defined,
    > might not be correctly aligned, might not point to an entity
    > of the referenced type, and might be a trap representation.
    >
    > with a footnote:
    >
    > The mapping functions for converting a pointer to an integer
    > or an integer to a pointer are intended to be consistent with
    > the addressing structure of the execution environment.
    >
    > (But that's not relevant to this code because, as I said, no conversion
    > is implied.)


    Haha, thanks for clarifying and correcting. Clearly I've been out of C
    programming so much that what I know no longer matches with current
    standards. I suppose I should go brush up my skills. :)

    Anyway, the bottom line to the original poster is "don't mix up integers
    and pointers unless you really know what you're doing", yes?


    --
    "C provides a programmer with more than enough rope to hang himself.
    C++ provides a firing squad, blindfold and last cigarette."
    - seen in comp.lang.c
    Angel, Jun 8, 2012
    #12
  13. Angel <> writes:
    [...]
    > Anyway, the bottom line to the original poster is "don't mix up integers
    > and pointers unless you really know what you're doing", yes?


    Pretty much. Conversions between pointers and integers are problematic
    (except for the special case of converting a null pointer constant, such
    as a literal 0, to a pointer type, which is well defined).

    On the other hand, pointer arithmetic is well defined in most cases:

    pointer + integer => pointer
    integer + pointer => pointer
    pointer - pointer => integer

    (except that it doesn't apply to void* or other pointers to incomplete
    types, or to function pointers, and going outside the bounds of a single
    object is undefined.)

    --
    Keith Thompson (The_Other_Keith) <http://www.ghoti.net/~kst>
    Will write code for food.
    "We must do something. This is something. Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"
    Keith Thompson, Jun 9, 2012
    #13
  14. Keith Thompson wrote:
    > Angel<> writes:
    > [...]
    >> Anyway, the bottom line to the original poster is "don't mix up integers

    [....]

    Only scenario I could think of is on a 68k System where
    one woud want to stick a function pointer into Address
    4, generate a Trap and hope memory wasn't corrupted :p


    --
    See why I hate Windows users?
    All pain, no gain.
    -Howard Chu
    Ralph Spitzner, Jun 9, 2012
    #14
  15. "rage" <> wrote in message
    news:...
    > Can someone please help me out on this?
    >
    > #include<stdio.h>
    > main()
    > {
    > int i;
    > int *j=10;
    > i=j+19;
    > printf("%d %d\n",j,i);
    > }
    >
    > The output is a garbage value (86) on my pc and ideone. Should it not be
    > 29?


    As others have correctly pointed out, you have violated a dozen or so
    constraints.

    Using "old style" C (prior to the ISO standards), here is the answer I would
    give:

    If you add an integer to a pointer, the integer is *scaled* by the size of
    the object that the pointer points to. An "int" on your machine must be
    four bytes, therefore 19 is multiplied by 4 before adding it to the 10.
    Thus you get 86. (4*19+10)

    One of the important things to remember here: arithmetic involving pointers
    is *scaled*.

    --

    numerist at aquaporin4 dot com
    Charles Richmond, Jun 11, 2012
    #15
    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. =?Utf-8?B?Q2FybG8gTWFyY2hlc29uaQ==?=

    Fire Code behind code AND Javascript code associated to a Button Click Event

    =?Utf-8?B?Q2FybG8gTWFyY2hlc29uaQ==?=, Feb 10, 2004, in forum: ASP .Net
    Replies:
    4
    Views:
    21,178
    =?Utf-8?B?Q2FybG8gTWFyY2hlc29uaQ==?=
    Feb 11, 2004
  2. Alan Silver
    Replies:
    1
    Views:
    1,674
    Alan Silver
    Sep 15, 2005
  3. keithb
    Replies:
    1
    Views:
    888
    Bruce Barker
    Mar 29, 2006
  4. Replies:
    0
    Views:
    456
  5. thedarkman
    Replies:
    5
    Views:
    701
    Denis McMahon
    Sep 14, 2010
Loading...

Share This Page