HOW this program is executing plz explain the program

Discussion in 'C Programming' started by manish sahu, Feb 13, 2010.

  1. manish sahu

    manish sahu Guest

    #include<stdio.h>
    #include<conio.h>

    main()
    {
    int i,j;

    clrscr();
    scanf("%d%d"+scanf("%d%d",&i,&j));
    printf("%d %d",i,j);
    getch();
    return 0;
    }
    manish sahu, Feb 13, 2010
    #1
    1. Advertising

  2. manish sahu

    santosh Guest

    manish sahu wrote:
    > #include<stdio.h>
    > #include<conio.h>
    >
    > main()
    > {
    > int i,j;
    >
    > clrscr();
    > scanf("%d%d"+scanf("%d%d",&i,&j));
    > printf("%d %d",i,j);
    > getch();
    > return 0;
    > }


    The program above is broken. Firstly conio.h and the functions
    clrscr() and getch() are not standard functions, but that's a minor
    issue. Even if all three are commented out, your program is still
    broken.

    The single argument to the first scanf() call invokes undefined
    behaviour, as it attempts to add an arbitrary int value (the return
    value of the second scanf() call) to the pointer value to the first
    character of a string literal. Adding integer values to a pointer
    value is not defined in standard C, but even assuming it results in
    simply another pointer value, the problem is now you're supplying a
    pointer value to an unknown region of memory, which may or may not
    contain a sensible format string for scanf() to interpret. It may not
    even contain a sensible string. If scanf() does encounter any format
    specifiers, it will attempt to perform the indicated conversion, but
    you don't supply scanf() any storage locations to store them in.

    It's just completely messed up. Don't learn from such code. You can't
    learn anything sensible from poking at it. Learn proper C from a good
    book.
    santosh, Feb 13, 2010
    #2
    1. Advertising

  3. manish sahu

    jacob navia Guest

    santosh a écrit :
    > Adding integer values to a pointer
    > value is not defined in standard C,


    WHAT??????

    Please santosh!!


    You should write ON HUNDRED TIMES

    "I should turn on my brain before posting"

    PointerValue+integer --> PointerValue+integer*element_size-->new pointer value!!!
    jacob navia, Feb 13, 2010
    #3
  4. manish sahu

    santosh Guest

    jacob navia wrote:
    > santosh a �crit :
    > > Adding integer values to a pointer
    > > value is not defined in standard C,

    >
    > WHAT??????
    >
    > Please santosh!!
    >
    >
    > You should write ON HUNDRED TIMES
    >
    > "I should turn on my brain before posting"
    >
    > PointerValue+integer --> PointerValue+integer*element_size-->new pointer value!!!


    Right. Sincere apologies to the OP. I was thinking about conversion of
    integer value to a pointer value.
    santosh, Feb 13, 2010
    #4
  5. manish sahu

    jacob navia Guest

    santosh a écrit :
    > jacob navia wrote:
    >> santosh a �crit :
    >>> Adding integer values to a pointer
    >>> value is not defined in standard C,

    >> WHAT??????
    >>
    >> Please santosh!!
    >>
    >>
    >> You should write ON HUNDRED TIMES
    >>
    >> "I should turn on my brain before posting"
    >>
    >> PointerValue+integer --> PointerValue+integer*element_size-->new pointer value!!!

    >
    > Right. Sincere apologies to the OP. I was thinking about conversion of
    > integer value to a pointer value.


    Yes, the rest of your post seemed OK.
    Anyway this can happen to anyone.

    jacob
    jacob navia, Feb 13, 2010
    #5
  6. manish sahu

    santosh Guest

    jacob navia wrote:
    > santosh a écrit :
    > > jacob navia wrote:
    > >> santosh a �crit :
    > >>> Adding integer values to a pointer
    > >>> value is not defined in standard C,
    > >> WHAT??????
    > >>
    > >> Please santosh!!
    > >>
    > >>
    > >> You should write ON HUNDRED TIMES
    > >>
    > >> "I should turn on my brain before posting"
    > >>
    > >> PointerValue+integer --> PointerValue+integer*element_size-->new pointer value!!!

    > >
    > > Right. Sincere apologies to the OP. I was thinking about conversion of
    > > integer value to a pointer value.

    >
    > Yes, the rest of your post seemed OK.
    > Anyway this can happen to anyone.


    It would be interesting if the OP could tell us where he picked up
    this snippet and what the original author claims it to demonstrate.

    To the OP: The following link is a good tutorial to start learning C
    from:

    <http://www.eskimo.com/~scs/cclass/cclass.html>
    santosh, Feb 13, 2010
    #6
  7. manish sahu

    Seebs Guest

    On 2010-02-13, santosh <> wrote:
    >> int i,j;
    >> scanf("%d%d"+scanf("%d%d",&i,&j));
    >> printf("%d %d",i,j);


    > The single argument to the first scanf() call invokes undefined
    > behaviour, as it attempts to add an arbitrary int value (the return
    > value of the second scanf() call) to the pointer value to the first
    > character of a string literal. Adding integer values to a pointer
    > value is not defined in standard C, but even assuming it results in
    > simply another pointer value, the problem is now you're supplying a
    > pointer value to an unknown region of memory, which may or may not
    > contain a sensible format string for scanf() to interpret.


    Actually, I don't think that's true.

    The only way this can not yield a viable value is if an input failure
    occurs before any conversion. Otherwise, it's going to be 0, 1, or 2,
    yielding "%d%d", "d%d", or "%d", respectively.

    > It may not
    > even contain a sensible string. If scanf() does encounter any format
    > specifiers, it will attempt to perform the indicated conversion, but
    > you don't supply scanf() any storage locations to store them in.


    And on at least some systems, that'll result by happy coincidence in it
    getting the values of &i and &j left around from the previous call.

    But it's still shitty code.

    -s
    --
    Copyright 2010, all wrongs reversed. Peter Seebach /
    http://www.seebs.net/log/ <-- lawsuits, religion, and funny pictures
    http://en.wikipedia.org/wiki/Fair_Game_(Scientology) <-- get educated!
    Seebs, Feb 13, 2010
    #7
  8. manish sahu <> writes:
    > #include<stdio.h>
    > #include<conio.h>
    >
    > main()
    > {
    > int i,j;
    >
    > clrscr();
    > scanf("%d%d"+scanf("%d%d",&i,&j));
    > printf("%d %d",i,j);
    > getch();
    > return 0;
    > }


    This is better in the sense that it's more portable and doesn't do
    rude things like clearing the screen, but it's still junk (I've
    also improved the layout, corrected the declaration of main,
    and added a new-line to the output).

    #include <stdio.h>

    int main(void)
    {
    int i, j;

    scanf("%d%d" + scanf("%d%d", &i, &j));
    printf("%d %d\n", i, j);
    return 0;
    }

    The inner scanf call is evaluated first. It will attempt to read two
    int values, as text, from stdin, and store them in i and j. Let's
    assume this succeeds.

    So far, we've consumed two strings representing int values from stdin,
    stored them in i and j, and returned the value 2 from scanf.

    Now the outer scanf call is equivalent to

    scanf("%d%d" + 2);

    which in turn is equivalent to

    scanf("%d");

    for reasons I can explain if anyone doesn't already understand it.

    This reads another string representing an int value from stdin and
    .... wait, what?

    The format string specifies that you're reading an int value,
    but no corresponding argument is provided, so we haven't specified
    where to store it. Undefined behavior. In practice, it's likely
    to store the third int value from stdin in the location pointed to
    by whatever address happens to be in the memory location where the
    second argument *would* have been.

    If the inner scanf call fails, it can return either 1 or 0, yielding
    a format string for the outer scanf of either "d%d" or "%d%d".
    "d%d" requires a literal 'd' on input, followed by an int value;
    "%d%d" requires two int values. In either case, the behavior
    is undefined because of the lack of following arguments; even
    if those arguments were provided, the failure is quietly ignored
    since the program doesn't check the result of the outer scanf call.
    Or if an input failure occurs before any conversion, it yields
    the value of EOF, which is negative (-1 on most implementations),
    resulting in yet another cause of undefined behavior.

    On my system, when I feed this program "100 200 300" as input, the
    output is "300 200". There's probably some argument to be made
    that this is the most likely result, based on where arguments are
    probably stored on the stack, but I won't waste my time constructing
    such an argument.

    Obfuscated code has its place. Things like this can be useful
    as puzzles to demonstrate how well you really know the language.
    *Wrong* obfuscated code can even be useful for similar reasons;
    knowing what's incorrect and why is as important as knowing
    how correct code behaves. But if someone proposed to include
    something like this in production code, physical violence would not
    be my immediate response, but it would be somewhere on the list.
    (That last part is a joke ... mostly.)

    --
    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, Feb 13, 2010
    #8
  9. On 2010-02-13, manish sahu <> wrote:
    > #include<stdio.h>
    > #include<conio.h>
    >


    This is unnecessary and non-portable, but fortunately(?) the
    functions you call from it(?) are also unnecessary so we can
    just imagine away that header, your call to clrscr() and the
    call to getch().

    > main()


    main() returns int. Writing that explicitly is clearer and
    more future-proof:
    int main(void)

    The void is also more specific; in theory just int main() could
    accept an arbritary number of arguments, so in C it is better to
    say int main(void).

    > {
    > int i,j;
    >
    > clrscr();
    > scanf("%d%d"+scanf("%d%d",&i,&j));


    The first argument to scanf is "%d%d" + n, where n is calculated
    as the return value of scanf(). If scanf reads both characters,
    the return value will be 2 and the argument will be "%d%d" + 2,
    or "%d". Now scanf() expects an int to go with that, and gets
    none, so you have invoked Undefined Behavior.

    That's the best case.

    Worst case, the second scanf() gets no valid input and returns 0,
    so the first scanf() is expecting /two/ integers as additional
    arguments, so again you have Undefined Behavior.

    In either case your program logic is traipsing over memory it
    doesn't own, and anything can happen, including but not limited
    to sending SIGWAKE to the demon daemon, who will draw demons
    from your nose.

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


    By this point, who knows what's happening.

    > getch();
    > return 0;
    > }
    Andrew Poelstra, Feb 13, 2010
    #9
  10. On Sat, 13 Feb 2010 01:39:48 -0800 (PST), manish sahu
    <> wrote:

    >#include<stdio.h>
    >#include<conio.h>
    >
    >main()
    >{
    > int i,j;
    >
    > clrscr();
    > scanf("%d%d"+scanf("%d%d",&i,&j));
    > printf("%d %d",i,j);
    > getch();
    > return 0;
    >}


    Please put your question in the body of your post, even if it just
    duplicates your subject.

    The program works only if you are very careful with your inputs. In
    other cases, it invokes undefined behavior which, among other things,
    means there is no explanation.

    The inner call to scanf accepts at most two integers. If you do not
    enter two integers, at least one of the two integers printed has an
    indeterminate value and evaluating it causes undefined behavior.

    If you do enter two integers, they must be of the form
    int_1 int_2 ??? <ENTER>
    where the quantity and choice of white space characters are irrelevant
    as long as there is one between the two integers and one after the
    second integer. The ??? represent additional optional data which will
    not be processed by this call to scanf. The use of the enter key
    assumes you are using a keyboard but your system may have other
    methods of determining that the input is complete.

    scanf will stop processing the input at the first character that is
    not part of int_2 and this character will be made available to the
    next attempt to read from stdin. At this point, both i and j have
    been set and scanf will return 2, indicating that two values were
    successfully converted.

    The argument of the outer call to scanf is a pointer value formed by
    the pointer arithmetic expression. The left operand of the addition
    operator is the address of the string literal which is stored in your
    program as an unnamed static array of char. The array consists of the
    five characters '%', 'd', '%', 'd', and '\0'. The address of this
    array is the address of the first '%'. The right operand is the int
    returned by scanf, which we are assuming is 2. The result of this
    addition is the address of the second '%'. Therefore, the effective
    argument passed to scanf is "%d".

    Thus, the outer call to scanf will accept at most one integer. One of
    the features of the %d conversion specifier is that it will skip over
    white space looking for the start of the integer. Assuming you did
    not enter any ??? data, it will skip over all the white space
    following int_2, including the '\n' generated by the enter key. It
    will then wait for you to enter more data. Presumably, you hit enter
    again. But this is just more white space to ignore. At this point,
    you must force end of file or enter a non-numeric character followed
    by the enter key. Either of these actions will cause the conversion
    to fail and scanf to return. You should have no trouble with the
    remaining code.

    If you enter any numeric data when scanf is waiting, or if you entered
    a characters sequence starting with a number after int_2, then this
    outer call to scanf will attempt to convert that data into an int
    value and store it somewhere. That somewhere would be specified by
    the next argument to scanf but there is no other argument. This also
    results in undefined behavior.

    In summary, the program may have worked but if it did so it is only
    because you cleverly, or luckily, avoided all the pitfalls.

    It is also possible that the program did not work properly but only
    appeared to. Improper input during either call to scanf results in
    undefined behavior. One of the more undesirable manifestations of
    undefined behavior is to appear to do what is expected, this time.

    --
    Remove del for email
    Barry Schwarz, Feb 13, 2010
    #10
  11. manish sahu

    Stefan Ram Guest

    manish sahu <> writes:
    >clrscr();
    >scanf("%d%d"+scanf("%d%d",&i,&j));


    This does something implementation-specified
    and then something undefined.
    Stefan Ram, Feb 13, 2010
    #11
  12. Barry Schwarz <> writes:
    > On Sat, 13 Feb 2010 01:39:48 -0800 (PST), manish sahu
    > <> wrote:
    >
    >>#include<stdio.h>
    >>#include<conio.h>
    >>
    >>main()
    >>{
    >> int i,j;
    >>
    >> clrscr();
    >> scanf("%d%d"+scanf("%d%d",&i,&j));
    >> printf("%d %d",i,j);
    >> getch();
    >> return 0;
    >>}

    >
    > Please put your question in the body of your post, even if it just
    > duplicates your subject.
    >
    > The program works only if you are very careful with your inputs. In
    > other cases, it invokes undefined behavior which, among other things,
    > means there is no explanation.


    The program's behavior is undefined no matter how careful you are
    with your inputs.

    [...]

    > Thus, the outer call to scanf will accept at most one integer. One of
    > the features of the %d conversion specifier is that it will skip over
    > white space looking for the start of the integer. Assuming you did
    > not enter any ??? data, it will skip over all the white space
    > following int_2, including the '\n' generated by the enter key. It
    > will then wait for you to enter more data. Presumably, you hit enter
    > again. But this is just more white space to ignore. At this point,
    > you must force end of file or enter a non-numeric character followed
    > by the enter key. Either of these actions will cause the conversion
    > to fail and scanf to return. You should have no trouble with the
    > remaining code.


    C99 7.19.6.2p2 (describing fscanf, but the same applies to scanf):

    If there are insufficient arguments for the format, the behavior
    is undefined. If the format is exhausted while arguments remain,
    the excess arguments are evaluated (as always) but are otherwise
    ignored.

    Note that the behavior is undefined if there are insufficient
    arguments *for the format*, whether any attempt is made to store
    values or not.

    In practice, this is likely to be harmless, but an implementation
    could attempt to access all the objects into which values might be
    stored, perhaps for the purpose of detecting this kind of problem
    before consuming any input.

    --
    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, Feb 13, 2010
    #12
    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. brian

    Size of my Struct? PLZ PLZ reply

    brian, Nov 23, 2004, in forum: C Programming
    Replies:
    7
    Views:
    405
    -berlin.de
    Nov 25, 2004
  2. Replies:
    1
    Views:
    362
  3. Replies:
    2
    Views:
    321
    Nick Keighley
    Nov 24, 2006
  4. Replies:
    1
    Views:
    328
  5. nocturnal
    Replies:
    1
    Views:
    506
    nocturnal
    Jul 10, 2009
Loading...

Share This Page