how this works ?

Discussion in 'C Programming' started by lector, Apr 4, 2008.

  1. lector

    lector Guest

    in my code i am seperate components or modules. suppose



    foo2.c

    int foo2(int *a)
    {
    /* some operations which vary the value of a
    the function returns 0 if successful or 1 if failure is
    encountered. */
    }

    foo.c

    #include "foo2.h"
    #include <stdio.h>
    int main(void)
    {
    int a,i;

    i= foo2(&a);
    if(i==1)
    {
    printf("failure");
    return(EXIT_FAILURE);
    }
    else
    {
    printf("%d",a);
    return(EXIT_SUCCESS);
    }

    }


    when call a function and pass adress to it then it is call by
    reference. the function foo2 will change the value at the address
    given to it as parameter. but my question is won't the variable be
    destroyed after the function foo2() is over ? if we make a variable
    extern then is it true that it will appear everywhere in the whole
    code with the same value ?
    lector, Apr 4, 2008
    #1
    1. Advertising

  2. lector

    Lew Pitcher Guest

    lector wrote:

    > in my code i am seperate components or modules. suppose
    >
    >
    >
    > foo2.c
    >
    > int foo2(int *a)
    > {
    > /* some operations which vary the value of a
    > the function returns 0 if successful or 1 if failure is
    > encountered. */
    > }
    >
    > foo.c
    >
    > #include "foo2.h"
    > #include <stdio.h>
    > int main(void)
    > {
    > int a,i;
    >
    > i= foo2(&a);
    > if(i==1)
    > {
    > printf("failure");
    > return(EXIT_FAILURE);
    > }
    > else
    > {
    > printf("%d",a);
    > return(EXIT_SUCCESS);
    > }
    >
    > }
    >
    >
    > when call a function and pass adress to it then it is call by
    > reference.


    No it isn't. C doesn't "call by reference". The
    foo2(&a)
    is a call by value, with the value being the "address" of the local variable
    a.

    > the function foo2 will change the value at the address
    > given to it as parameter.


    Yes.

    > but my question is won't the variable be
    > destroyed after the function foo2() is over ?


    Certainly, the /argument/ passed to foo2() will be lost. But that argument
    wasn't the local variable in main(), it was a "copy" of the /address/ of
    the local variable in main().


    > if we make a variable
    > extern then is it true that it will appear everywhere in the whole
    > code with the same value ?


    Yes and no

    "extern" says that the variable is defined outside of the translation unit.
    That means that the variable must be defined in some other translation
    unit.

    Global variables may be defined as "global within the translation unit, but
    not accessable outside of the unit" by making them
    "static"

    And, of course, local variables take precedence over global variables

    int Var;

    void Func(void)
    {
    int Var;
    Var = 7; /* changes the Var defined within Func() */
    }


    --
    Lew Pitcher

    Master Codewright & JOAT-in-training | Registered Linux User #112576
    http://pitcher.digitalfreehold.ca/ | GPG public key available by request
    ---------- Slackware - Because I know what I'm doing. ------
    Lew Pitcher, Apr 4, 2008
    #2
    1. Advertising

  3. lector

    lector Guest

    I will post another question which I believe is not offtopic with
    regard to this thread

    I am trying to build this link list here with following modules -

    create.c : This module create the link list.

    print.c : This module print the link list

    ll.c: Contains main routine.

    /* create.h */

    #ifndef create_list
    #define create_list

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

    typedef struct node_struct
    {
    int data;
    struct node_struct *next;
    }node;

    extern void create_link_list(node *, int);

    #endif


    /* create.c */

    #include "create.h"

    void create_link_list(node *root, int n)
    {
    node *p, *prev;
    int i;

    for(i=0; i<n; i++)
    {
    p = malloc(sizeof(node));
    p->next = NULL;
    printf("Enter data\n");
    scanf("%d", &p->data);
    if(root == NULL)
    {
    root = p;
    prev = root;
    }
    else
    {
    prev->next = p;
    prev = p;
    }
    }
    }

    /* print.h */
    #ifndef print_h
    #define print_h

    #include "create.h"

    extern void print_link_list(node *);

    #endif

    /* print.c */
    #include "print.h"

    void print_link_list(node *root)
    {
    node *p;

    p = root;

    while(p != NULL)
    {
    printf("%d\n", p->data);
    p = p->next;
    }

    }

    /* ll.c */
    #include "create.h"
    #include "print.h"

    int main(void)
    {
    node *root;
    int n;
    printf("Enter how many numbers\n");
    scanf("%d", &n);
    root = NULL;
    create_link_list(root, n);
    print_link_list(root);
    return 0;

    }


    The program compile successfuly and I could link all the obj files
    without any errors or warnings. When I execute the
    application(ll.exe), I can input all the numbers but the link list is
    not printed. I think the problem lies in the fact that the link list
    has been created but the copy of updated pointer to the root node is
    not available as it got destroyed once the create routine terminated.
    As root was null, nothing was printed on the screen. I think it will
    be better to return the pointer to root node but what if a function
    causes exceptions and a 1 or 0 has to be returned to indicate if the
    function executed successfuly or not ? We can only return 1 value from
    a function. You cannot return an integer(0/1) and a pointer to root
    node at the same time. Not sure if this explanation is accurate but I
    really hope some one clarify what is going on here as this is the
    first time I tried to write a link list program split into many source
    files.
    lector, Apr 5, 2008
    #3
  4. lector

    lector Guest

    On Apr 4, 8:26 pm, Richard Heathfield <> wrote:
    > lector said:
    >
    > > in my code i am seperate components or modules. suppose

    >
    > > foo2.c

    >
    > > int foo2(int *a)
    > > {
    > > /* some operations which vary the value of a
    > > the function returns 0 if successful or 1 if failure is
    > > encountered. */

    >
    > For example:
    >
    > #include <stddef.h>
    >
    > int foo2(int *a)
    > {
    > if(a != NULL)
    > {
    > *a = 6;
    > }
    > return a == NULL;
    >
    > } /* was that so hard to type? */
    > > }

    >
    > > foo.c

    >
    > > #include "foo2.h"

    >
    > Not supplied. I presume it looks something like this:
    >
    > #ifndef H_FOO2
    > #define H_FOO2 1
    > int foo2(int *);
    > #endif
    >
    > > #include <stdio.h>
    > > int main(void)
    > > {
    > > int a,i;

    >
    > > i= foo2(&a);
    > > if(i==1)
    > > {
    > > printf("failure");
    > > return(EXIT_FAILURE);

    >
    > You don't need the parentheses around the expression in a return
    > statement. But, to use EXIT_FAILURE or EXIT_SUCCESS, you do need
    > to #include <stdlib.h>
    >
    > > }
    > > else
    > > {
    > > printf("%d",a);
    > > return(EXIT_SUCCESS);
    > > }

    >
    > > }

    >
    > > when call a function and pass adress to it then it is call by
    > > reference.

    >
    > No, a pointer value is passed. C is always pass-by-value. But a copy of a
    > pointer value is still a pointer value, and can still be used to access
    > the original object.
    >
    > > the function foo2 will change the value at the address
    > > given to it as parameter.

    >
    > It will change the value of the object to which the pointer parameter
    > points, yes.
    >
    > > but my question is won't the variable be
    > > destroyed after the function foo2() is over ?

    >
    > The copy of the pointer is destroyed, but so what?
    >
    > > if we make a variable
    > > extern then is it true that it will appear everywhere in the whole
    > > code with the same value ?

    >
    > If you use extern to qualify an object declaration, you are promising the
    > compiler that a definition exists at file scope, somewhere in the program.
    > It is up to you to ensure that this promise is kept. Whilst I decline to
    > be dogmatic about it, I would suggest that you avoid this feature wherever
    > possible, as file scope variables increase coupling (and maintenance time)
    > far in excess of the supposed benefits they bring in ease of writing.
    > Learn to see limited scope as a friend rather than an enemy.
    >
    > Example of extern, using three files:
    >
    > /* foo.h */
    > #ifndef H_FOO
    > #define H_FOO 1
    > extern int fsobj;
    > extern void foo(void);
    > #endif
    >
    > /* foo.c */
    > #include "foo.h"
    >
    > int fsobj = 42; /* initialised once only, at startup */
    >
    > void foo(void)
    > {
    > fsobj = 6;
    >
    > }
    >
    > /* main.c */
    > #include <stdio.h>
    > #include "foo.h"
    >
    > int main(void)
    > {
    > printf("Before: %d\n", fsobj);
    > foo();
    > printf("After: %d\n", fsobj);
    > return 0;
    >
    > }


    Sigh. I think my first post does not make any sense(was too tierd
    last night) and its not what I really wanted to ask. Please refer to
    the link list program that I just posted.
    lector, Apr 5, 2008
    #4
  5. lector

    lector Guest

    On Apr 4, 8:26 pm, Richard Heathfield <> wrote:
    <snip>
    > Example of extern, using three files:
    >
    > /* foo.h */
    > #ifndef H_FOO
    > #define H_FOO 1
    > extern int fsobj;
    > extern void foo(void);
    > #endif
    >
    > /* foo.c */
    > #include "foo.h"
    >
    > int fsobj = 42; /* initialised once only, at startup */
    >
    > void foo(void)
    > {
    > fsobj = 6;
    >
    > }
    >
    > /* main.c */
    > #include <stdio.h>
    > #include "foo.h"
    >
    > int main(void)
    > {
    > printf("Before: %d\n", fsobj);
    > foo();
    > printf("After: %d\n", fsobj);
    > return 0;
    >
    > }


    Wait. How did it print 42 first and then 6 ? Why is it that you can
    only initialize an external variable outside the scope of a function ?
    When I tried to comment the 'int fsobj = 42' bit and initialized
    fsobj in foo() instead, I get an error.
    lector, Apr 5, 2008
    #5
  6. lector

    Default User Guest

    lector wrote:


    > void create_link_list(node *root, int n)
    > {
    > node *p, *prev;
    > int i;
    >
    > for(i=0; i<n; i++)
    > {
    > p = malloc(sizeof(node));
    > p->next = NULL;
    > printf("Enter data\n");
    > scanf("%d", &p->data);
    > if(root == NULL)
    > {
    > root = p;
    > prev = root;
    > }
    > else
    > {
    > prev->next = p;
    > prev = p;
    > }
    > }
    > }


    > The program compile successfuly and I could link all the obj files
    > without any errors or warnings. When I execute the
    > application(ll.exe), I can input all the numbers but the link list is
    > not printed. I think the problem lies in the fact that the link list
    > has been created but the copy of updated pointer to the root node is
    > not available as it got destroyed once the create routine terminated.


    I didn't get destroyed, it got lost. See the FAQs:

    <http://c-faq.com/ptrs/passptrinit.html>



    Brian
    Default User, Apr 5, 2008
    #6
  7. lector

    lector Guest

    On Apr 5, 12:19 pm, "Default User" <> wrote:

    > I didn't get destroyed, it got lost. See the FAQs:
    >
    > <http://c-faq.com/ptrs/passptrinit.html>


    Yeah, I read both 4.8 and 20.1. What happens is that you pass a copy
    of pointer(which you want to change), the called function changes the
    pointer value but then this changed value is lost after the function
    is over. IF it was data that we wanted to modify, it would have worked
    fine. So i guess it is better to treat the root pointer as 'data'
    itself and pass a pointer to root pointer.
    crete_link_list(**root, n);
    print_link_list(**root, n);

    This will mean even though the value of double pointer to root node is
    lost, I still have the value of the root pointer
    lector, Apr 5, 2008
    #7
  8. lector

    Willem Guest

    lector wrote:
    ) Yeah, I read both 4.8 and 20.1. What happens is that you pass a copy
    ) of pointer(which you want to change), the called function changes the
    ) pointer value but then this changed value is lost after the function
    ) is over. IF it was data that we wanted to modify, it would have worked
    ) fine. So i guess it is better to treat the root pointer as 'data'
    ) itself and pass a pointer to root pointer.
    ) create_link_list(**root, n);

    Or you just return the new pointer:

    node *create_link_list(n)

    ) print_link_list(**root, n);

    Does print_link_list need to change the root pointer ?


    SaSW, Willem
    --
    Disclaimer: I am in no way responsible for any of the statements
    made in the above text. For all I know I might be
    drugged or something..
    No I'm not paranoid. You all think I'm paranoid, don't you !
    #EOT
    Willem, Apr 5, 2008
    #8
  9. lector

    lector Guest

    On Apr 5, 7:37 pm, Willem <> wrote:

    > Or you just return the new pointer:
    >
    > node *create_link_list(n)


    One can do that but what if you can't malloc in create function
    because of some error ? For that, it might be necessary to return an
    int (EXIT_SUCCESS/EXIT_FAILURE) for checking.

    > ) print_link_list(**root, n);
    >
    > Does print_link_list need to change the root pointer ?


    No, it only needs to print the list but even for that you need the
    updated root pointer or else nothing is printed on the screen because
    of root's null value.
    lector, Apr 5, 2008
    #9
  10. lector

    Willem Guest

    lector wrote:
    ) On Apr 5, 7:37 pm, Willem <> wrote:
    )
    )> Or you just return the new pointer:
    )>
    )> node *create_link_list(n)
    )
    ) One can do that but what if you can't malloc in create function
    ) because of some error ? For that, it might be necessary to return an
    ) int (EXIT_SUCCESS/EXIT_FAILURE) for checking.

    How does malloc() return failure then ?

    )> ) print_link_list(**root, n);
    )>
    )> Does print_link_list need to change the root pointer ?
    )
    ) No, it only needs to print the list but even for that you need the
    ) updated root pointer or else nothing is printed on the screen because
    ) of root's null value.

    And why is *root not 'the updated root pointer' ?


    SaSW, Willem
    --
    Disclaimer: I am in no way responsible for any of the statements
    made in the above text. For all I know I might be
    drugged or something..
    No I'm not paranoid. You all think I'm paranoid, don't you !
    #EOT
    Willem, Apr 5, 2008
    #10
  11. lector <> writes:
    > On Apr 5, 7:37 pm, Willem <> wrote:
    >> Or you just return the new pointer:
    >>
    >> node *create_link_list(n)

    >
    > One can do that but what if you can't malloc in create function
    > because of some error ? For that, it might be necessary to return an
    > int (EXIT_SUCCESS/EXIT_FAILURE) for checking.


    I advise against using EXIT_SUCCESS and EXIT_FAILURE as status codes
    for functions other than main. It's not absolutely guaranteed that
    they have distinct values (though I've never heard of a system where
    they don't).

    Many library functions return zero for success, non-zero for failure;
    that's a reasonable convention to follow.

    --
    Keith Thompson (The_Other_Keith) <>
    Nokia
    "We must do something. This is something. Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"
    Keith Thompson, Apr 5, 2008
    #11
  12. lector

    santosh Guest

    Keith Thompson wrote:

    > lector <> writes:
    >> On Apr 5, 7:37 pm, Willem <> wrote:
    >>> Or you just return the new pointer:
    >>>
    >>> node *create_link_list(n)

    >>
    >> One can do that but what if you can't malloc in create function
    >> because of some error ? For that, it might be necessary to return an
    >> int (EXIT_SUCCESS/EXIT_FAILURE) for checking.

    >
    > I advise against using EXIT_SUCCESS and EXIT_FAILURE as status codes
    > for functions other than main. It's not absolutely guaranteed that
    > they have distinct values (though I've never heard of a system where
    > they don't).


    You mean that there may be implementations where EXIT_SUCCESS ==
    EXIT_FAILURE? If so how will the environment distinguish between the
    two?

    > Many library functions return zero for success, non-zero for failure;
    > that's a reasonable convention to follow.
    santosh, Apr 26, 2008
    #12
  13. lector

    Richard Guest

    santosh <> writes:

    > Keith Thompson wrote:
    >
    >> lector <> writes:
    >>> On Apr 5, 7:37 pm, Willem <> wrote:
    >>>> Or you just return the new pointer:
    >>>>
    >>>> node *create_link_list(n)
    >>>
    >>> One can do that but what if you can't malloc in create function
    >>> because of some error ? For that, it might be necessary to return an
    >>> int (EXIT_SUCCESS/EXIT_FAILURE) for checking.

    >>
    >> I advise against using EXIT_SUCCESS and EXIT_FAILURE as status codes
    >> for functions other than main. It's not absolutely guaranteed that
    >> they have distinct values (though I've never heard of a system where
    >> they don't).

    >
    > You mean that there may be implementations where EXIT_SUCCESS ==
    > EXIT_FAILURE? If so how will the environment distinguish between the
    > two?
    >
    >> Many library functions return zero for success, non-zero for failure;
    >> that's a reasonable convention to follow.


    There would be more chance of a chip bit accidentally toggling then
    them not being the same IMO.
    Richard, Apr 26, 2008
    #13
  14. lector

    santosh Guest

    pete wrote:

    > santosh wrote:
    >> Keith Thompson wrote:
    >>
    >>> lector <> writes:
    >>>> On Apr 5, 7:37 pm, Willem <> wrote:
    >>>>> Or you just return the new pointer:
    >>>>>
    >>>>> node *create_link_list(n)
    >>>> One can do that but what if you can't malloc in create function
    >>>> because of some error ? For that, it might be necessary to return
    >>>> an int (EXIT_SUCCESS/EXIT_FAILURE) for checking.
    >>> I advise against using EXIT_SUCCESS and EXIT_FAILURE as status codes
    >>> for functions other than main. It's not absolutely guaranteed that
    >>> they have distinct values (though I've never heard of a system where
    >>> they don't).

    >>
    >> You mean that there may be implementations where EXIT_SUCCESS ==
    >> EXIT_FAILURE? If so how will the environment distinguish between the
    >> two?

    >
    > There is no requirement for the system
    > to be able to distinguish between the two.
    >
    > void main (void)


    I don't get it. From n1256 section 7.20 para 3:

    +-----
    | EXIT_FAILURE
    | and
    | EXIT_SUCCESS
    |
    | which expand to integer constant expressions that can be used as the
    | argument to the exit function to return unsuccessful or successful
    | termination status, respectively, to the host environment;
    +-----

    The above seems to be indicate pretty clearly that EXIT_FAILURE and
    EXIT_SUCCESS return different termination statuses to the host. How
    could this happen if the implementation could not distinguish between
    them?

    <snip>
    santosh, Apr 26, 2008
    #14
  15. lector

    Default User Guest

    santosh wrote:


    > The above seems to be indicate pretty clearly that EXIT_FAILURE and
    > EXIT_SUCCESS return different termination statuses to the host. How
    > could this happen if the implementation could not distinguish between
    > them?


    What are you saying? If a host system doesn't have a way to distinguish
    successful versus non-successful return, you can't have a C compiler?




    Brian
    Default User, Apr 26, 2008
    #15
  16. lector

    santosh Guest

    Default User wrote:

    > santosh wrote:
    >
    >
    >> The above seems to be indicate pretty clearly that EXIT_FAILURE and
    >> EXIT_SUCCESS return different termination statuses to the host. How
    >> could this happen if the implementation could not distinguish between
    >> them?

    >
    > What are you saying? If a host system doesn't have a way to
    > distinguish successful versus non-successful return, you can't have a
    > C compiler?


    As far as I can see EXIT_SUCCESS and EXIT_FAILURE merely return
    successful termination status and unsuccessful termination status
    respectively to the host environment. Whether the host is able to
    distinguish between the two is not relevant to the C implementation.
    What it can't do is to set EXIT_SUCCESS to be equal to EXIT_FAILURE.
    They return different termination statuses and therefore must be
    different.

    That was what I was arguing in response to Keith Thompson's post
    up-thread.
    santosh, Apr 26, 2008
    #16
  17. lector

    Default User Guest

    santosh wrote:

    > Default User wrote:
    >
    > > santosh wrote:
    > >
    > >
    > >> The above seems to be indicate pretty clearly that EXIT_FAILURE and
    > >> EXIT_SUCCESS return different termination statuses to the host. How
    > >> could this happen if the implementation could not distinguish

    > between >> them?
    > >
    > > What are you saying? If a host system doesn't have a way to
    > > distinguish successful versus non-successful return, you can't have
    > > a C compiler?

    >
    > As far as I can see EXIT_SUCCESS and EXIT_FAILURE merely return
    > successful termination status and unsuccessful termination status
    > respectively to the host environment.


    Which have to be values meaningful to the host.

    > Whether the host is able to
    > distinguish between the two is not relevant to the C implementation.
    > What it can't do is to set EXIT_SUCCESS to be equal to EXIT_FAILURE.
    > They return different termination statuses and therefore must be
    > different.


    I'm not sure the Standard says they must be different. If the Standard
    doesn't specify that they are required to be non-equal, and the host
    system can't distinguish, then the as-if rule would seem to say that
    they could be the same for some implementation.




    Brian
    Default User, Apr 26, 2008
    #17
  18. lector

    Chris Torek Guest

    In article <fuvmrh$ih2$>
    santosh <> wrote:
    >As far as I can see EXIT_SUCCESS and EXIT_FAILURE merely return
    >successful termination status and unsuccessful termination status
    >respectively to the host environment.


    Right.

    >Whether the host is able to distinguish between the two is not
    >relevant to the C implementation.


    Maybe. (I think this is correct, but I think one can at least
    argue that it is not. This gets to be one of those philosophical
    questions, like "if a tree falls in the forest and there is no one
    around to observe it, does it make `a noise'", where the answer
    hinges on the exact defintion of `noise'. If noise means "any
    sound", then -- assuming we understand physics correctly -- it does
    make sound and hence noise, but if it means "a sound that annoys
    a person", then since there is no person being annoyed, it makes
    no `noise'.)

    >What it can't do is to set EXIT_SUCCESS to be equal to EXIT_FAILURE.
    >They return different termination statuses and therefore must be
    >different.


    But then we can appeal to the "as-if" rule and claim that, if the
    user cannot tell whether they returned different statuses, the
    compiler is allowed to have them return the same status, or even
    no status at all. In which case, perhaps the compiler's freedom
    to alter or remove the value returned from main() extends to further
    freedom to "#define" both with the same value. In other words, if
    the effect is not observable, the compiler can do whatever it likes:
    we will not even be able to tell whether it has done anything.

    There is another argument one can make, with clearer ground (less
    appeal to philosophy). Consider the following C code fragment:

    switch (f()) {
    case EXIT_SUCCESS: ... code for success ... break;
    case EXIT_FAILURE: ... code for failure ... break;
    }

    If EXIT_SUCCESS and EXIT_FAILURE are allowed, in some implementation,
    to be "#define"d as the same value, this code will not compile
    (because we are not allowed to have two "case"s with identical
    constants). If they must be different, the code will compile.
    The question then boils down to whether Standard C guarantees
    that this code will compile, which *is* an observable effect.

    Because I think that Standard C guarantees this code will compile,
    I think that an implementation is not allowed to "#define" both as
    the same constant, even on a host where the return value from main()
    (or the value passed to exit() or _Exit()) is always discarded.
    --
    In-Real-Life: Chris Torek, Wind River Systems
    Salt Lake City, UT, USA (40°39.22'N, 111°50.29'W) +1 801 277 2603
    email: gmail (figure it out) http://web.torek.net/torek/index.html
    Chris Torek, Apr 26, 2008
    #18
  19. lector

    santosh Guest

    Default User wrote:
    > santosh wrote:
    >> Default User wrote:
    >> > santosh wrote:
    >> >
    >> >> The above seems to be indicate pretty clearly that EXIT_FAILURE
    >> >> and EXIT_SUCCESS return different termination statuses to the
    >> >> host. How could this happen if the implementation could not
    >> >> distinguish between them?
    >> >
    >> > What are you saying? If a host system doesn't have a way to
    >> > distinguish successful versus non-successful return, you can't have
    >> > a C compiler?

    >>
    >> As far as I can see EXIT_SUCCESS and EXIT_FAILURE merely return
    >> successful termination status and unsuccessful termination status
    >> respectively to the host environment.

    >
    > Which have to be values meaningful to the host.


    As I see it, this is outside the scope of the standard.

    >> Whether the host is able to
    >> distinguish between the two is not relevant to the C implementation.
    >> What it can't do is to set EXIT_SUCCESS to be equal to EXIT_FAILURE.
    >> They return different termination statuses and therefore must be
    >> different.

    >
    > I'm not sure the Standard says they must be different. If the Standard
    > doesn't specify that they are required to be non-equal, and the host
    > system can't distinguish, then the as-if rule would seem to say that
    > they could be the same for some implementation.


    The "as-if" rule really only makes sense if it, in some way, simplifies
    things for the implementation or makes things more efficient. Strictly
    speaking you may be right in your analysis, but I still say that making
    EXIT_SUCCESS and EXIT_FAILURE the same is something only a DS9k would
    do.

    Also this can break code registered with atexit which might execute
    different code depending on what termination status was passed to exit.
    Again this might happen only in theory, but it's nevertheless another
    point in favour of keeping EXIT_SUCCESS and EXIT_FAILURE distinct from
    each other.
    santosh, Apr 27, 2008
    #19
  20. lector

    santosh Guest

    Chris Torek wrote:

    > In article <fuvmrh$ih2$>
    > santosh <> wrote:
    >>As far as I can see EXIT_SUCCESS and EXIT_FAILURE merely return
    >>successful termination status and unsuccessful termination status
    >>respectively to the host environment.

    >
    > Right.
    >
    >>Whether the host is able to distinguish between the two is not
    >>relevant to the C implementation.

    >
    > Maybe. (I think this is correct, but I think one can at least
    > argue that it is not. This gets to be one of those philosophical
    > questions, like "if a tree falls in the forest and there is no one
    > around to observe it, does it make `a noise'", where the answer
    > hinges on the exact defintion of `noise'. If noise means "any
    > sound", then -- assuming we understand physics correctly -- it does
    > make sound and hence noise, but if it means "a sound that annoys
    > a person", then since there is no person being annoyed, it makes
    > no `noise'.)
    >
    >>What it can't do is to set EXIT_SUCCESS to be equal to EXIT_FAILURE.
    >>They return different termination statuses and therefore must be
    >>different.

    >
    > But then we can appeal to the "as-if" rule and claim that, if the
    > user cannot tell whether they returned different statuses, the
    > compiler is allowed to have them return the same status, or even
    > no status at all. In which case, perhaps the compiler's freedom
    > to alter or remove the value returned from main() extends to further
    > freedom to "#define" both with the same value. In other words, if
    > the effect is not observable, the compiler can do whatever it likes:
    > we will not even be able to tell whether it has done anything.
    >
    > There is another argument one can make, with clearer ground (less
    > appeal to philosophy). Consider the following C code fragment:
    >
    > switch (f()) {
    > case EXIT_SUCCESS: ... code for success ... break;
    > case EXIT_FAILURE: ... code for failure ... break;
    > }
    >
    > If EXIT_SUCCESS and EXIT_FAILURE are allowed, in some implementation,
    > to be "#define"d as the same value, this code will not compile
    > (because we are not allowed to have two "case"s with identical
    > constants). If they must be different, the code will compile.
    > The question then boils down to whether Standard C guarantees
    > that this code will compile, which *is* an observable effect.
    >
    > Because I think that Standard C guarantees this code will compile,
    > I think that an implementation is not allowed to "#define" both as
    > the same constant, even on a host where the return value from main()
    > (or the value passed to exit() or _Exit()) is always discarded.


    An even stronger case (IMHO) for making EXIT_FAILURE and EXIT_SUCCESS
    different might be the following code:

    #include <stdlib.h>

    int term_type;

    void called_by_atexit(void) {
    if (term_type == EXIT_SUCCESS) {
    /* some code */
    }
    else if (term_type == EXIT_FAILURE) {
    /* some other code */
    }
    else {
    /* yet some other code */
    }
    return;
    }

    int main(void) {
    atexit(called_by_atexit);
    return(term_type = EXIT_FAILURE);
    }

    In called_by_atexit() the wrong block of code will be executed.
    santosh, Apr 27, 2008
    #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. Razor
    Replies:
    2
    Views:
    950
    Razor
    Aug 19, 2003
  2. Brian McGonigle
    Replies:
    1
    Views:
    545
    Andrew Kavanaugh
    Aug 20, 2004
  3. F. GEIGER
    Replies:
    3
    Views:
    756
    F. GEIGER
    Aug 6, 2004
  4. Alexander Burger

    getMethod() works and works not

    Alexander Burger, Nov 27, 2010, in forum: Java
    Replies:
    25
    Views:
    1,720
    Alexander Burger
    Nov 29, 2010
  5. abargaddon
    Replies:
    1
    Views:
    186
    clintmazur
    Feb 4, 2008
Loading...

Share This Page