C++ static destructor guaranteed to be called?

Discussion in 'Java' started by Paul J. Lucas, Oct 1, 2005.

  1. If I'm writing some native code using the C++ JNI API and my
    C++ code has a static object with a destructor, is it
    guaranteed that said destructor will be called before the
    process terminates (as it would be if this were plain C++)?

    I would think the answer would be "yes" since this is outside
    the purview of the JVM.

    - Paul
     
    Paul J. Lucas, Oct 1, 2005
    #1
    1. Advertising

  2. Paul J. Lucas

    Joan Guest

    "Paul J. Lucas" <>
    wrote in message
    news:paA%e.2247$...
    > If I'm writing some native code using the C++ JNI API and my
    > C++ code has a static object with a destructor, is it
    > guaranteed that said destructor will be called before the
    > process terminates (as it would be if this were plain C++)?
    >
    > I would think the answer would be "yes" since this is outside
    > the purview of the JVM.
    >
    > - Paul


    Why don't you write a little test program. It is not a waste of
    time for you cuz you have to learn jni anyway.
     
    Joan, Oct 1, 2005
    #2
    1. Advertising

  3. Joan <> wrote:
    >
    > "Paul J. Lucas" <>
    > wrote in message
    > news:paA%e.2247$...
    > > If I'm writing some native code using the C++ JNI API and my
    > > C++ code has a static object with a destructor, is it
    > > guaranteed that said destructor will be called before the
    > > process terminates (as it would be if this were plain C++)?
    > >
    > > I would think the answer would be "yes" since this is outside
    > > the purview of the JVM.

    >
    > Why don't you write a little test program. It is not a waste of
    > time for you cuz you have to learn jni anyway.


    Just because I write a test program and it does what I want on
    my platform doesn't mean it's guaranteed on all platforms.
    Hence my question.

    I already know JNI, thanks.

    - Paul
     
    Paul J. Lucas, Oct 1, 2005
    #3
  4. Paul J. Lucas

    Roedy Green Guest

    On Sat, 01 Oct 2005 18:02:23 GMT,
    (Paul J. Lucas) wrote or
    quoted :

    > If I'm writing some native code using the C++ JNI API and my
    > C++ code has a static object with a destructor, is it
    > guaranteed that said destructor will be called before the
    > process terminates (as it would be if this were plain C++)?
    >
    > I would think the answer would be "yes" since this is outside
    > the purview of the JVM.


    I would guess no. In an ordinary C++ app, at some point you call the
    C++ equivalent of exit(). At that point C++ can do whatever shutdown
    processing it wants.

    When a Java app shuts down, exit() has no knowledge of the C++
    runtime. There in no hook into the C++ shutdown code. For all exit
    knows, you wrote all your JNI in pure assembler and there is no C++
    runtime. It does not even know that any JNI code has been run.


    --
    Canadian Mind Products, Roedy Green.
    http://mindprod.com Again taking new Java programming contracts.
     
    Roedy Green, Oct 1, 2005
    #4
  5. "Roedy Green" <> wrote in
    message > I would guess no. In an ordinary C++ app, at some point you
    call the
    > C++ equivalent of exit(). At that point C++ can do whatever shutdown
    > processing it wants.
    >
    > When a Java app shuts down, exit() has no knowledge of the C++
    > runtime. There in no hook into the C++ shutdown code. For all exit
    > knows, you wrote all your JNI in pure assembler and there is no C++
    > runtime. It does not even know that any JNI code has been run.


    Assuming by statics the OP means static variables in functions.

    I believe things may be slightly better than that. I think most OSes
    have a standard way in which a library (.dll/.so/whatever) can execute
    some of its own code on first being loaded (when it would run ctors for
    any global objects), and then cleanup prior to being unloaded (dtor'ing
    the globals and any statics that have been ctor'd).

    I've just tested this (on Win98; your milage may vary) by putting a
    global object with ctor and dtor in a DLL that is picked up at run-time
    by LoadLibrary/GetProcAddress (i.e. the client that "links" to it does
    nothing to acknowledge the C++ runtime) and the the ctor and dtor were
    both called. I'd imagine similar would hold in Unix, and further that
    the mechanism described is similar to how System.loadLibrary causes
    native methods to be bound.

    I believe exit() quits "gracefully", unloading libraries as it goes,
    whereas abort() just destroys the running process with no cleanup.

    Hope this helps

    John.
     
    John Perks and Sarah Mount, Oct 2, 2005
    #5
  6. "Paul J. Lucas" <> wrote in
    message news:paA%e.2247$...
    > If I'm writing some native code using the C++ JNI API and my
    > C++ code has a static object with a destructor, is it
    > guaranteed that said destructor will be called before the
    > process terminates (as it would be if this were plain C++)?
    >
    > I would think the answer would be "yes" since this is outside
    > the purview of the JVM.


    I would expect this to be platform/compiler-specific. A pure C++
    implementation can guarantee this, but whether that guarantee holds with a
    non-C++ main and non-C++ exit function will depend upon mechanism. If it
    were me, I'd write a test program, observe its behavior, in particular
    whether the C++ runtime gets invoked on exit, and proceed from there.
     
    Mike Schilling, Oct 2, 2005
    #6
  7. "Paul J. Lucas" wrote:
    > Joan <> wrote:
    >>
    >> "Paul J. Lucas" wrote:
    >> > If I'm writing some native code using the C++ JNI API and my
    >> > C++ code has a static object with a destructor, is it
    >> > guaranteed that said destructor will be called before the
    >> > process terminates (as it would be if this were plain C++)?
    >> >
    >> > I would think the answer would be "yes" since this is outside
    >> > the purview of the JVM.

    >>
    >> Why don't you write a little test program. It is not a waste of
    >> time for you cuz you have to learn jni anyway.

    >
    > Just because I write a test program and it does what I want on
    > my platform doesn't mean it's guaranteed on all platforms.
    > Hence my question.

    Imagine you would write the test program and it would *not* do what you want
    on your platform. Or it would sometimes do what you want, and sometimes not.
    If so, that would disprove your preconception. Isn't this enough motivation
    for a test?
    >
    > I already know JNI, thanks.


    --
    "TFritsch$t-online:de".replace(':','.').replace('$','@')
     
    Thomas Fritsch, Oct 3, 2005
    #7
  8. Thomas Fritsch <> wrote:
    > "Paul J. Lucas" wrote:


    > > Just because I write a test program and it does what I want on
    > > my platform doesn't mean it's guaranteed on all platforms.
    > > Hence my question.


    > Imagine you would write the test program and it would *not* do what you want
    > on your platform.


    Then I have my answer.

    > Or it would sometimes do what you want, and sometimes not.


    Again, I have my answer.

    > Isn't this enough motivation for a test?


    How do you know I didn't already write a test for my platform?
    Read my original post carefully. I never said one way or the
    other.

    - Paul
     
    Paul J. Lucas, Oct 3, 2005
    #8
  9. "Paul J. Lucas" <> wrote:
    > Thomas Fritsch <> wrote:
    >> "Paul J. Lucas" wrote:

    >
    >> > Just because I write a test program and it does what I want on
    >> > my platform doesn't mean it's guaranteed on all platforms.
    >> > Hence my question.

    >
    >> Imagine you would write the test program and it would *not* do what you
    >> want
    >> on your platform.

    >
    > Then I have my answer.
    >
    >> Or it would sometimes do what you want, and sometimes not.

    >
    > Again, I have my answer.
    >
    >> Isn't this enough motivation for a test?

    >
    > How do you know I didn't already write a test for my platform?
    > Read my original post carefully. I never said one way or the
    > other.


    Paul,
    I actually read your original post carefully and noticed you didn't say it
    one way or the other. I noticed you were almost but not absolutely sure,
    that the test would always say "yes" (the C++ destructor is called upon
    exit). But I interpreted your posts in a way, that your assumption was
    mainly based on your JVM knowledge instead of on test-results. So I assumed
    (may be wrongly) you didn't test it.
    As you said correctly: If the test says "no" one single time, one knows it
    doesn't say "yes" every time. This is, what makes the test so valuable, and
    why I recommended it.
    My answer was not meant as an offence. Sorry, if it could be misunderstood
    as such.
    --
    Thomas
     
    Thomas Fritsch, Oct 3, 2005
    #9
  10. Paul J. Lucas

    E.J. Pitt Guest

    Paul J. Lucas wrote:
    > If I'm writing some native code using the C++ JNI API and my
    > C++ code has a static object with a destructor, is it
    > guaranteed that said destructor will be called before the
    > process terminates (as it would be if this were plain C++)?
    >
    > I would think the answer would be "yes" since this is outside
    > the purview of the JVM.


    This behaviour is mandated by the C++ standard. The only platform I am
    aware of where it doesn't happen according to specification is Novell
    Netware when you have a C++ NLM that terminates abnormally, and that
    information is some years old.
     
    E.J. Pitt, Oct 8, 2005
    #10
  11. E.J. Pitt wrote:
    > Paul J. Lucas wrote:
    >
    >> If I'm writing some native code using the C++ JNI API and my
    >> C++ code has a static object with a destructor, is it
    >> guaranteed that said destructor will be called before the
    >> process terminates (as it would be if this were plain C++)?
    >>
    >> I would think the answer would be "yes" since this is outside
    >> the purview of the JVM.

    >
    >
    > This behaviour is mandated by the C++ standard. The only platform I am
    > aware of where it doesn't happen according to specification is Novell
    > Netware when you have a C++ NLM that terminates abnormally, and that
    > information is some years old.


    Windows processes which are terminated by TerminateProcess are killed
    instantly without any chance to run any further code. It doesn't matter
    what language the process is written in.

    Mark Thornton
     
    Mark Thornton, Oct 8, 2005
    #11
  12. Paul J. Lucas

    Roedy Green Guest

    On Sat, 01 Oct 2005 18:02:23 GMT,
    (Paul J. Lucas) wrote or
    quoted :

    > If I'm writing some native code using the C++ JNI API and my
    > C++ code has a static object with a destructor, is it
    > guaranteed that said destructor will be called before the
    > process terminates (as it would be if this were plain C++)?
    >
    > I would think the answer would be "yes" since this is outside
    > the purview of the JVM.


    That presumes C++'s exit is called to trigger shutdown sequences. If
    you exited Java that way yes, but then you would lose the Java
    shutdown sequences.
    --
    Canadian Mind Products, Roedy Green.
    http://mindprod.com Again taking new Java programming contracts.
     
    Roedy Green, Oct 9, 2005
    #12
  13. Paul J. Lucas

    E.J. Pitt Guest

    Roedy Green wrote:
    > On Sat, 01 Oct 2005 18:02:23 GMT,
    > (Paul J. Lucas) wrote or
    > quoted :
    >
    >
    >> If I'm writing some native code using the C++ JNI API and my
    >> C++ code has a static object with a destructor, is it
    >> guaranteed that said destructor will be called before the
    >> process terminates (as it would be if this were plain C++)?
    >>
    >> I would think the answer would be "yes" since this is outside
    >> the purview of the JVM.

    >
    >
    > I would guess no. In an ordinary C++ app, at some point you call the
    > C++ equivalent of exit(). At that point C++ can do whatever shutdown
    > processing it wants.
    >
    > When a Java app shuts down, exit() has no knowledge of the C++
    > runtime. There in no hook into the C++ shutdown code. For all exit
    > knows, you wrote all your JNI in pure assembler and there is no C++
    > runtime. It does not even know that any JNI code has been run.


    Any C program which contains C++ gets a C++ version of main() and
    exit(), one way or the other. This is organized by the compiler and the
    linker between them.
     
    E.J. Pitt, Oct 9, 2005
    #13
  14. Paul J. Lucas

    Chris Uppal Guest

    E.J. Pitt wrote:

    > Any C program which contains C++ gets a C++ version of main() and
    > exit(), one way or the other. This is organized by the compiler and the
    > linker between them.


    "the" compiler ? The jvm is packaged as a DLL (or equivalent). There is no
    guarantee what compiler was used to generate it, nor indeed what language it
    was written in. If that DLL invokes "exit()" then it's difficult to see how
    /any/ statement can be made about what that does -- especially in respect to
    the expectations of the invoking program.

    That -- presumably -- is why JNI has a means for the invoking program to set an
    exit hook which will be called by the JVM if/when java code uses System.exit()
    (or equivalent). (I'd clean forgotten about that hook, btw, which is why I
    didn't mention that it would solve the OP's problem earlier in this thread :-(

    -- chris
     
    Chris Uppal, Oct 9, 2005
    #14
  15. Paul J. Lucas

    Stefan Ram Guest

    "E.J. Pitt" <> writes:
    >Any C program which contains C++ gets a C++ version of main() and
    >exit(), one way or the other.


    What is a "C programm which contains C++"?
     
    Stefan Ram, Oct 9, 2005
    #15
  16. "E.J. Pitt" <> wrote in message
    news:u552f.11812$...
    >
    > Any C program which contains C++ gets a C++ version of main() and exit(),
    > one way or the other. This is organized by the compiler and the linker
    > between them.


    I'll just observe here that the C++ standard defines the 'extern "C" '
    construct for communicating between C and C++, and makes no guarantees of
    any kind about what it does, since cross-language behavior is ouitside its
    purview.
     
    Mike Schilling, Oct 9, 2005
    #16
  17. Paul J. Lucas

    Chris Head Guest

    -----BEGIN PGP SIGNED MESSAGE-----
    Hash: SHA1

    Greetings,
    I believe the answer to this question is "yes", at least under Win32. In
    Win32, your JNI code is contained in a DLL. In a Win32 DLL, there is a
    magic entry point which is automatically invoked by the operating system
    immediately after the DLL loads and immediately before it unloads
    (INCLUDING if the process is terminated with ExitProcess(), as it would
    be even if the main program was written in assembly - but NOT if by
    TerminateProcess(), which hardly anyone does anyway). The Visual C++
    runtime provides its own definition of this function which initializes
    and destroys global (and presumably static) objects. I have tested this
    functionality personally: when a DLL containing a global object is
    loaded with LoadLibrary(), the global object's constructor runs. When
    FreeLibrary() unloads the library, the destructor runs. It doesn't
    matter what language or what program loads and unloads the DLL: the
    invocation of the load/unload callback (often referred to as DllMain)
    occurs as a function of the operating system, and the CRT associated
    with the DLL provides the entry point which initializes and destroys
    globals.

    I think Linux also provides a similar pair of magic functions in .SO files.

    Chris

    Paul J. Lucas wrote:
    > If I'm writing some native code using the C++ JNI API and my
    > C++ code has a static object with a destructor, is it
    > guaranteed that said destructor will be called before the
    > process terminates (as it would be if this were plain C++)?
    >
    > I would think the answer would be "yes" since this is outside
    > the purview of the JVM.
    >
    > - Paul


    -----BEGIN PGP SIGNATURE-----
    Version: GnuPG v1.4.2 (MingW32)
    Comment: GnuPT 2.7.2
    Comment: Using GnuPG with Thunderbird - http://enigmail.mozdev.org

    iD8DBQFDTfMi6ZGQ8LKA8nwRAgrjAKCVhV3hMrYq8OCT8dc2xaNW4iEVAQCeIRm5
    9fmpBjG+hHfs5a02ToziKpQ=
    =n6s7
    -----END PGP SIGNATURE-----
     
    Chris Head, Oct 13, 2005
    #17
  18. Paul J. Lucas

    Roedy Green Guest

    On Sun, 09 Oct 2005 09:07:38 GMT, "E.J. Pitt"
    <> wrote or quoted :

    >Any C program which contains C++ gets a C++ version of main() and
    >exit(), one way or the other. This is organized by the compiler and the
    >linker between them.


    That is half the battle. The other half is to make sure that code gets
    called when Java shuts down.
    --
    Canadian Mind Products, Roedy Green.
    http://mindprod.com Again taking new Java programming contracts.
     
    Roedy Green, Oct 13, 2005
    #18
  19. Paul J. Lucas

    E.J. Pitt Guest

    Chris Uppal wrote:
    > E.J. Pitt wrote:
    >
    >
    >>Any C program which contains C++ gets a C++ version of main() and
    >>exit(), one way or the other. This is organized by the compiler and the
    >>linker between them.

    >
    >
    > "the" compiler ? The jvm is packaged as a DLL (or equivalent). There is no
    > guarantee what compiler was used to generate it, nor indeed what language it
    > was written in. If that DLL invokes "exit()" then it's difficult to see how
    > /any/ statement can be made about what that does -- especially in respect to
    > the expectations of the invoking program.
    >
    > That -- presumably -- is why JNI has a means for the invoking program to set an
    > exit hook which will be called by the JVM if/when java code uses System.exit()
    > (or equivalent). (I'd clean forgotten about that hook, btw, which is why I
    > didn't mention that it would solve the OP's problem earlier in this thread :-(
    >
    > -- chris


    What I meant was that in a program containing a mixture of C and C++,
    the C++ compiler put hooks into the object code such that the C++
    runtime library is linked in which in turn will lead to destructors of
    static objects being called on exit(). However thinking about it some
    more, being about 12 years since I have done it, the requirement was
    that main() be compiled by C++. I don't believe that happens in Java JNI
    so basically I was probably wrong.
     
    E.J. Pitt, Oct 14, 2005
    #19
  20. Paul J. Lucas

    Roedy Green Guest

    On Thu, 13 Oct 2005 05:39:47 GMT, Chris Head <>
    wrote or quoted :

    >In a Win32 DLL, there is a
    >magic entry point which is automatically invoked by the operating system
    >immediately after the DLL loads and immediately before it unloads


    But DLLs can hang around for a long time after the app closes right?
    So how does that work?
    --
    Canadian Mind Products, Roedy Green.
    http://mindprod.com Again taking new Java programming contracts.
     
    Roedy Green, Oct 19, 2005
    #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. Razvan
    Replies:
    5
    Views:
    4,476
    Razvan
    Sep 9, 2004
  2. Paul J. Lucas
    Replies:
    117
    Views:
    12,644
    Tim Tyler
    Sep 27, 2005
  3. Replies:
    8
    Views:
    527
    Ben Pope
    Mar 13, 2006
  4. Jimmy Hartzell
    Replies:
    0
    Views:
    426
    Jimmy Hartzell
    May 19, 2008
  5. Jimmy Hartzell
    Replies:
    2
    Views:
    1,175
    Jimmy Hartzell
    May 20, 2008
Loading...

Share This Page