anything like oninit() in 'C'?

Discussion in 'C Programming' started by tkk, Jul 10, 2003.

  1. tkk

    tkk Guest

    Hi All,
    How can a programmer instruct 'C' compiler to execute some
    user defined function before calling main() routine? 'C' provides
    flexibility to do the same while exiting by means of "onexit" (or)
    "atexit" routines.

    KK
     
    tkk, Jul 10, 2003
    #1
    1. Advertising

  2. On 9 Jul 2003 23:43:28 -0700, tkk wrote:
    > Hi All,
    > How can a programmer instruct 'C' compiler to execute some
    > user defined function before calling main() routine?


    First of all, there is no 'the C compiler'. Any compiler-related
    questions are off-topic here. This newsgoup's just here for the C
    language.

    The program starts at the entry point, which is main() by default
    (off-topic however, gnu's linker (and probably others as well) allows
    specification of an alternative entry point).
    So let's assume you can change the entry point, and that's what you
    want. It's just changing the name of main(). Calling a function
    called main() from that is just plain wrapping. What's the point?
    Consider this:

    int blah (int argc, char *argv[])
    {
    /* some pre-main code i can't think of */
    return main (argc, argv);
    }
    int main (int argc, char *argv[])
    {
    /* code */
    return 0;
    }

    Pointless! Why not just place blah()'s code right at the top of main(),
    you'll get the same effect, and much cleaner, and more portable, and
    more sane.

    > 'C' provides
    > flexibility to do the same while exiting by means of "onexit" (or)
    > "atexit" routines.


    Oh boy. You want to set the function run before main() using a
    function, like on_exit()? Where's the function going to be called from,
    main() or the entry point you specified?

    --
    main(int c,char*k,char*s){c>0?main(0,"adceoX$_k6][^hn","-7\
    0#05&'40$.6'+).3+1%30"),puts(""):*s?c=!c?-*s:(putchar(45),c
    ),putchar(main(c,k+=*s-c*-1,s+1)):(s=0);return!s?10:10+*k;}
     
    Pieter Droogendijk, Jul 10, 2003
    #2
    1. Advertising

  3. tkk

    Dan Pop Guest

    In <> (tkk) writes:

    >How can a programmer instruct 'C' compiler to execute some
    >user defined function before calling main() routine? 'C' provides
    >flexibility to do the same while exiting by means of "onexit" (or)
    >"atexit" routines.


    Standard C provides no such feature. GNU C provides the constructor
    attribute for this purpose.

    Dan
    --
    Dan Pop
    DESY Zeuthen, RZ group
    Email:
     
    Dan Pop, Jul 10, 2003
    #3
  4. On Thu, 10 Jul 2003, Pieter Droogendijk wrote:
    >
    > On 9 Jul 2003 23:43:28 -0700, tkk wrote:
    > > Hi All,
    > > How can a programmer instruct 'C' compiler to execute some
    > > user defined function before calling main() routine?

    <snip>
    > > 'C' provides
    > > flexibility to do the same while exiting by means of "onexit" (or)
    > > "atexit" routines.

    >
    > Oh boy. You want to set the function run before main() using a
    > function, like on_exit()? Where's the function going to be called from,
    > main() or the entry point you specified?


    Oh, obviously - from the entry point you specified!

    void my_entry_handler(void)
    {
    atinit(my_entry_handler);

    vbuf = 0xA000;
    if (!(zbuf = malloc(64000))) exit(EXIT_FAILURE);
    return;
    }

    C0x will also include the 'comefrom' keyword, to provide symmetry
    with C89's 'goto' statement.

    -Arthur
     
    Arthur J. O'Dwyer, Jul 10, 2003
    #4
  5. On Thu, 10 Jul 2003 10:09:37 -0400 (EDT), Arthur J. O'Dwyer wrote:
    >
    > On Thu, 10 Jul 2003, Pieter Droogendijk wrote:
    > > Oh boy. You want to set the function run before main() using a
    > > function, like on_exit()? Where's the function going to be called
    > > from, main() or the entry point you specified?

    >
    > Oh, obviously - from the entry point you specified!
    >
    > void my_entry_handler(void)
    > {
    > atinit(my_entry_handler);
    >
    > vbuf = 0xA000;
    > if (!(zbuf = malloc(64000))) exit(EXIT_FAILURE);
    > return;
    > }


    This would just allocate 64000 bytes and then exit. You're returning
    from the entry point, exiting the program.

    int my_entry_handler(int argc, char *argv[])
    {
    atinit(my_entry_handler);

    vbuf = 0xA000;
    if (!(zbuf = malloc(64000))) exit(EXIT_FAILURE);
    return main (argc,argv);
    }

    this might be more useful, but in my opinion still pointless.


    --
    main(int c,char*k,char*s){c>0?main(0,"adceoX$_k6][^hn","-7\
    0#05&'40$.6'+).3+1%30"),puts(""):*s?c=!c?-*s:(putchar(45),c
    ),putchar(main(c,k+=*s-c*-1,s+1)):(s=0);return!s?10:10+*k;}
     
    Pieter Droogendijk, Jul 10, 2003
    #5
  6. On Thu, 10 Jul 2003, Pieter Droogendijk wrote:
    >
    > On Thu, 10 Jul 2003 10:09:37 -0400 (EDT), Arthur J. O'Dwyer wrote:
    > >
    > > On Thu, 10 Jul 2003, Pieter Droogendijk wrote:
    > > > Oh boy. You want to set the function run before main() using a
    > > > function, like on_exit()? Where's the function going to be called
    > > > from, main() or the entry point you specified?

    > >
    > > Oh, obviously - from the entry point you specified!
    > >
    > > void my_entry_handler(void)
    > > {
    > > atinit(my_entry_handler);
    > >
    > > vbuf = 0xA000;
    > > if (!(zbuf = malloc(64000))) exit(EXIT_FAILURE);
    > > return;
    > > }

    >
    > This would just allocate 64000 bytes and then exit. You're returning
    > from the entry point, exiting the program.


    atexit()-handled functions don't have to call exit() themselves.
    (If they did, how could you register more than one?) Thus
    atinit()-registered functions don't have to call main() themselves.
    The startup code handles it. ;-)

    -Arthur
     
    Arthur J. O'Dwyer, Jul 10, 2003
    #6
  7. [OT] Re: anything like oninit() in 'C'?

    > Oh, obviously - from the entry point you specified!
    >
    > void my_entry_handler(void)
    > {
    > atinit(my_entry_handler);
    >
    > vbuf = 0xA000;
    > if (!(zbuf = malloc(64000))) exit(EXIT_FAILURE);
    > return;
    > }


    hehe, mode 13h? :)

    -- Nuclear / the Lab --
     
    John Tsiombikas (Nuclear / the Lab), Jul 10, 2003
    #7
  8. tkk

    Dan Pop Guest

    In <> Martien Verbruggen <> writes:

    >On 10 Jul 2003 12:44:22 GMT,
    > Dan Pop <> wrote:
    >> In <> Martien Verbruggen <> writes:

    >
    >[snip of reasons why one might want stuff called before main()]
    >
    >About atexit():
    >
    >>>[1] although I never have used it myself, and would probably consider it
    >>>bad design if I saw it in a program without a pretty decent explanation
    >>>of the programmer.

    >>
    >> This technique allows you to call exit() anywhere in your program.
    >> The atexit-registered functions will take care of the necessary clean up,
    >> including saving whatever user data is worth saving at that point.

    >
    >Yes, which is why I would probably flag its use as bad design. I don't
    >like exit() being called from just any old place in a program or, even
    >worse, library. IMO a well-designed program has only one exit point, and


    You're confusing religion and good design practices.

    >a programmer deciding that that is not the case should, again IMO,
    >provide a decent explanation as to why they decided to exit(), instead
    >of returning an error and letting the calling code deal with the
    >problem.
    >
    >Expediency isn't always a good reason, BTW.


    Simplifying the code structure without sacrificing anything else is
    *always* a good reason.

    Propagating a fatal error condition occuring deep inside the program
    up to the main function has a significant impact in terms of code
    complexity. If atexit-registered functions can remove the *real* need for
    doing it, it is pointless to do it for purely religious reasons.

    Dan
    --
    Dan Pop
    DESY Zeuthen, RZ group
    Email:
     
    Dan Pop, Jul 11, 2003
    #8
  9. On Thu, 10 Jul 2003 12:44:22 UTC, (Dan Pop) wrote:

    > The usual reason is because you don't have access to the code of main().
    > You're writing a library and you want to be sure that certain


    Has nothing to do with main but with the method the library gets
    loaded. So the right point would be to check the OS how it works while
    it loads a library. The OS may (or may not) have an interface that
    gets called when the library gets loaded. Has nothing to do with C but
    C knows nothing about libraries too.

    > A more exotic reason is to have some C code automatically executed before
    > a program written in another language starts its own execution.


    It is main() that gets automagically executed when a program gets
    executed. Between the OS an main there is the C Runtime Library that
    does the magic: initialison of static and extern class variables,
    creating heap, stack or equivalent things. Ask your compiler if it is
    open enough to describe the internals. Ask the other language
    compilers how it builds its interfaces to C.

    The simplest method would be to build a library thet can called from
    other languages, using the loader interface to make own initialisons.

    If all that is really impossible then use a trick to preserve the work
    with uninitialised data. Use a static variable, initialise it
    statically with an value that idetifies the library as uninitialised -
    and thest in each API that variable for its state and either let the
    app fail or make the initialisons under cover then.

    main() is the name of the entrypoint a C program gets called from the
    RTL. The OS calls always the RTL when it activates the execution of an
    application. So if your main is written in another language then the
    RTL of that language is executed before the main of that app. gets
    executed. Even the C RTL will then not initialised.

    Each library has its own entry point that gets called from the system
    loader when the library gets loaded.

    But all that is higly implementation defined, because there is
    absolutely nothing in the standard that describes how an
    implementation has to hande the startup of an application and/or a
    library. So you've study the relevant interfaces of your OS and your
    compiler to find the answer.

    --
    Tschau/Bye

    Herbert Rosenau
    http://www.pc-rosenau.de eComStation Reseller in Germany
    eCS 1.1 GA englisch wird jetzt ausgeliefert
     
    Herbert Rosenau, Jul 11, 2003
    #9
  10. tkk

    Greg Comeau Guest

    In article <bemhao$bu2$>, Dan Pop <> wrote:
    >It has nothing to do with C simply because C has chosen to ignore the
    >issue. C++ and GNU C both support it, without having to mess with OS
    >interfaces.


    it?
    --
    Greg Comeau/ 4.3.0.1: FULL CORE LANGUAGE, INCLUDING TC1
    Comeau C/C++ ONLINE ==> http://www.comeaucomputing.com/tryitout
    World Class Compilers: Breathtaking C++, Amazing C99, Fabulous C90.
    Comeau C/C++ with Dinkumware's Libraries... Have you tried it?
     
    Greg Comeau, Jul 11, 2003
    #10
  11. On Fri, 11 Jul 2003, Greg Comeau wrote:
    >
    > In article <bemhao$bu2$>, Dan Pop <> wrote:
    > >It has nothing to do with C simply because C has chosen to ignore the
    > >issue. C++ and GNU C both support it, without having to mess with OS
    > >interfaces.

    >
    > it?


    The ability of modules to run their own code at startup, before main()
    runs, without forcing the client to include calls to module_init() or
    the like as the first statements in main(). I don't know whether GCC
    supports this, but I'm inclined to believe it. And C++ sort-of supports
    it through the constructors of static-lifetime objects, AIUI:

    <OT>

    class ModuleInit
    {
    private:
    ModuleInit(void) { perform_startup_code(); }
    static ModuleInit hack;
    };

    </OT>

    Standard C doesn't have anything like this capability.

    -Arthur
     
    Arthur J. O'Dwyer, Jul 11, 2003
    #11
  12. tkk

    Malcolm Guest

    "Arthur J. O'Dwyer" <> wrote in message
    > Maybe a #pragma would work:
    >
    > #pragma atinit(foo_init)
    > void foo_init(void) { ... }
    >

    How about using the "entry" keyword (now unreserved, I fear) ?
     
    Malcolm, Jul 11, 2003
    #12
  13. [snips]

    On Fri, 11 Jul 2003 11:08:04 +1000, Martien Verbruggen wrote:

    >> This technique allows you to call exit() anywhere in your program.
    >> The atexit-registered functions will take care of the necessary clean up,
    >> including saving whatever user data is worth saving at that point.

    >
    > Yes, which is why I would probably flag its use as bad design. I don't
    > like exit() being called from just any old place in a program or, even
    > worse, library.


    Indeed; I once coded against a library - image manipulation, IIRC - which
    did just that: exit on memory allocation failure. As an undocumented
    effect, of course.

    It *could* have simply reported the error, then perhaps I could have freed
    up some memory or done something else, but no... just insta-barf.

    Damned stupid design.

    --
    http://rkc.silversapphire.com
    Managed Migration from Windows to Linux
     
    Kelsey Bjarnason, Jul 13, 2003
    #13
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Guest
    Replies:
    2
    Views:
    560
    Natty Gur
    Jul 13, 2003
  2. Guest
    Replies:
    2
    Views:
    3,110
    Guest
    Jul 16, 2003
  3. poi
    Replies:
    0
    Views:
    394
  4. Sally
    Replies:
    1
    Views:
    482
    bruce barker
    Apr 15, 2004
  5. Patrick Kowalzick
    Replies:
    5
    Views:
    479
    Patrick Kowalzick
    Mar 14, 2006
Loading...

Share This Page