From: cthuang@zerosan.UUCP (Chin Huang)
Newsgroups: comp.lang.c++
Subject: Re: Order of static object construction/destruction
Date: 10 Apr 1992 00:23:15 EDT
Organization: Cthulhu in '92 Presidential Campaign Headquarters

In article <69897@ut-emx.uucp> Jamshid Afshar wrote:
> So whatever order your compiler chooses to construct your program's
> static objects, it must destroy them all in the reverse order.

[ Deleted bug report in which Borland C++ fails to destroy static objects
  in the reverse order in which they were constructed. ]

Here is an unofficial patch to the Borland C++ 3.0 startup code I got
from a colleague.  Rather than posting copyrighted code and getting a
horde of lawyers at my door, I'm posting a context diff.  After applying
the patch to the files in the \BORLANDC\LIB\STARTUP directory (or wherever
you installed them), run BUILD-C0.BAT to rebuild the startup modules.

diff -c old/c0.asm new/c0.asm
*** old/c0.asm	Mon Nov 11 03:00:00 1991
--- new/c0.asm	Fri Mar 10 00:10:50 1992
***************
*** 392,398 ****
                  mov     es, cs:DGROUP@@
                  mov     si,offset DGROUP:InitStart      ;si = start of table
                  mov     di,offset DGROUP:InitEnd        ;di = end of table
!                 call    StartExit
  
  ;       ExitCode = main(argc,argv,envp);
  
--- 392,398 ----
                  mov     es, cs:DGROUP@@
                  mov     si,offset DGROUP:InitStart      ;si = start of table
                  mov     di,offset DGROUP:InitEnd        ;di = end of table
!                 call    Initialize
  
  ;       ExitCode = main(argc,argv,envp);
  
***************
*** 432,438 ****
                  push    di
                  mov     si,offset DGROUP:ExitStart
                  mov     di,offset DGROUP:ExitEnd
!                 call    StartExit
                  pop     di
                  pop     si
                  ret
--- 432,438 ----
                  push    di
                  mov     si,offset DGROUP:ExitStart
                  mov     di,offset DGROUP:ExitEnd
!                 call    Cleanup
                  pop     di
                  pop     si
                  ret
***************
*** 599,611 ****
  addrhigh        dw      ?
  SE              ENDS
  
! StartExit       proc near
! @@Start:        cmp     si,offset DGROUP:InitStart      ; startup or exit?
!                 je      @@StartLow              ; it's startup
!                 xor     ah,ah                   ; start with high priority
!                 jmp     short @@SaveEnd
! @@StartLow:     mov     ah,0ffh                 ;start with lowest priority
! @@SaveEnd:      mov     dx,di                   ;set sentinel to end of table
                  mov     bx,si                   ;bx = start of table
  
  @@TopOfTable:   cmp     bx,di                   ;and the end of the table?
--- 599,607 ----
  addrhigh        dw      ?
  SE              ENDS
  
! Initialize      proc near
! @@Start:        mov     ah,0ffh                 ;start with lowest priority
!                 mov     dx,di                   ;set sentinel to end of table
                  mov     bx,si                   ;bx = start of table
  
  @@TopOfTable:   cmp     bx,di                   ;and the end of the table?
***************
*** 612,623 ****
                  je      @@EndOfTable            ;yes, exit the loop
                  cmp     es:[bx.calltype],NOTUSED;check the call type
                  je      @@Next
!                 cmp     si,offset DGROUP:InitStart      ; startup or exit?
!                 je      @@CompareHigh           ; it's startup
!                 cmp     ah,es:[bx.priority]     ; it's exit
!                 jmp     short @@CheckPrior      ; if priority too low, skip
! @@CompareHigh:  cmp     es:[bx.priority],ah     ;check the priority
! @@CheckPrior:   ja      @@Next                  ;too high?  skip
                  mov     ah,es:[bx.priority]     ;keep priority
                  mov     dx,bx                   ;keep index in dx
  @@Next:         add     bx,SIZE SE              ;bx = next item in table
--- 608,615 ----
                  je      @@EndOfTable            ;yes, exit the loop
                  cmp     es:[bx.calltype],NOTUSED;check the call type
                  je      @@Next
!                 cmp     es:[bx.priority],ah     ;check the priority
!                 ja      @@Next                  ;too high?  skip
                  mov     ah,es:[bx.priority]     ;keep priority
                  mov     dx,bx                   ;keep index in dx
  @@Next:         add     bx,SIZE SE              ;bx = next item in table
***************
*** 624,629 ****
--- 616,657 ----
                  jmp     @@TopOfTable
  
  @@EndOfTable:   cmp     dx,di                   ;did we exhaust the table?
+                 je      @@Done                  ;yes, quit
+                 mov     bx,dx                   ;bx = highest priority item
+                 cmp     es:[bx.calltype],PNEAR  ;is it near or far?
+                 mov     es:[bx.calltype],NOTUSED;wipe the call type
+                 push    es                      ;save es
+                 je      @@NearCall
+ 
+ @@FarCall:      call    DWORD PTR es:[bx.addrlow]
+                 pop     es                      ;restore es
+                 jmp     short @@Start
+ 
+ @@NearCall:     call    WORD PTR es:[bx.addrlow]
+                 pop     es                      ;restore es
+                 jmp     short @@Start
+ 
+ @@Done:         ret
+                 endp
+ 
+ Cleanup         proc near
+ @@Start:        mov     ah,0                    ;start with highest priority
+                 mov     dx,-1                   ;set sentinel
+                 mov     bx,di                   ;bx = end of table
+ 
+ @@Next:         cmp     bx,si                   ;at the start of the table?
+                 je      @@EndOfTable            ;yes, exit the loop
+                 sub     bx,SIZE SE              ;bx = next item in table
+ 
+                 cmp     es:[bx.calltype],NOTUSED;check the call type
+                 je      @@Next
+                 cmp     es:[bx.priority],ah     ;check the priority
+                 jb      @@Next                  ;too low?  skip
+                 mov     ah,es:[bx.priority]     ;keep priority
+                 mov     dx,bx                   ;keep index in dx
+                 jmp     @@Next
+ 
+ @@EndOfTable:   cmp     dx,-1                   ;did we exhaust the table?
                  je      @@Done                  ;yes, quit
                  mov     bx,dx                   ;bx = highest priority item
                  cmp     es:[bx.calltype],PNEAR  ;is it near or far?
diff -c old/c0d.asm new/c0d.asm
*** old/c0d.asm	Mon Nov 11 03:00:00 1991
--- new/c0d.asm	Fri Mar 10 00:11:02 1992
***************
*** 318,328 ****
  
  Cleanup         proc near
  @@Start:        mov     ah,0                    ;start with highest priority
!                 mov     dx,di                   ;set sentinel to end of table
!                 mov     bx,si                   ;bx = start of table
  
! @@TopOfTable:   cmp     bx,di                   ;and the end of the table?
                  je      @@EndOfTable            ;yes, exit the loop
                  cmp     es:[bx.calltype],NOTUSED;check the call type
                  je      @@Next
                  cmp     es:[bx.priority],ah     ;check the priority
--- 318,330 ----
  
  Cleanup         proc near
  @@Start:        mov     ah,0                    ;start with highest priority
!                 mov     dx,-1                   ;set sentinel
!                 mov     bx,di                   ;bx = end of table
  
! @@Next:         cmp     bx,si                   ;at the start of the table?
                  je      @@EndOfTable            ;yes, exit the loop
+                 sub     bx,SIZE SE              ;bx = next item in table
+ 
                  cmp     es:[bx.calltype],NOTUSED;check the call type
                  je      @@Next
                  cmp     es:[bx.priority],ah     ;check the priority
***************
*** 329,338 ****
                  jb      @@Next                  ;too low?  skip
                  mov     ah,es:[bx.priority]     ;keep priority
                  mov     dx,bx                   ;keep index in dx
! @@Next:         add     bx,SIZE SE              ;bx = next item in table
!                 jmp     @@TopOfTable
  
! @@EndOfTable:   cmp     dx,di                   ;did we exhaust the table?
                  je      @@Done                  ;yes, quit
                  mov     bx,dx                   ;bx = highest priority item
                  cmp     es:[bx.calltype],PNEAR  ;is it near or far?
--- 331,339 ----
                  jb      @@Next                  ;too low?  skip
                  mov     ah,es:[bx.priority]     ;keep priority
                  mov     dx,bx                   ;keep index in dx
!                 jmp     @@Next
  
! @@EndOfTable:   cmp     dx,-1                   ;did we exhaust the table?
                  je      @@Done                  ;yes, quit
                  mov     bx,dx                   ;bx = highest priority item
                  cmp     es:[bx.calltype],PNEAR  ;is it near or far?
diff -c old/c0w.asm new/c0w.asm
*** old/c0w.asm	Mon Nov 11 03:00:00 1991
--- new/c0w.asm	Fri Mar 10 00:11:20 1992
***************
*** 320,330 ****
  
  Cleanup         proc near
  @@Start:        mov     ah,0                    ;start with highest priority
!                 mov     dx,di                   ;set sentinel to end of table
!                 mov     bx,si                   ;bx = start of table
  
! @@TopOfTable:   cmp     bx,di                   ;and the end of the table?
                  je      @@EndOfTable            ;yes, exit the loop
                  cmp     es:[bx.calltype],NOTUSED;check the call type
                  je      @@Next
                  cmp     es:[bx.priority],ah     ;check the priority
--- 320,332 ----
  
  Cleanup         proc near
  @@Start:        mov     ah,0                    ;start with highest priority
!                 mov     dx,-1                   ;set sentinel
!                 mov     bx,di                   ;bx = end of table
  
! @@Next:         cmp     bx,si                   ;at the start of the table?
                  je      @@EndOfTable            ;yes, exit the loop
+                 sub     bx,SIZE SE              ;bx = next item in table
+ 
                  cmp     es:[bx.calltype],NOTUSED;check the call type
                  je      @@Next
                  cmp     es:[bx.priority],ah     ;check the priority
***************
*** 331,340 ****
                  jb      @@Next                  ;too low?  skip
                  mov     ah,es:[bx.priority]     ;keep priority
                  mov     dx,bx                   ;keep index in dx
! @@Next:         add     bx,SIZE SE              ;bx = next item in table
!                 jmp     @@TopOfTable
  
! @@EndOfTable:   cmp     dx,di                   ;did we exhaust the table?
                  je      @@Done                  ;yes, quit
                  mov     bx,dx                   ;bx = highest priority item
                  cmp     es:[bx.calltype],PNEAR  ;is it near or far?
--- 333,341 ----
                  jb      @@Next                  ;too low?  skip
                  mov     ah,es:[bx.priority]     ;keep priority
                  mov     dx,bx                   ;keep index in dx
!                 jmp     @@Next
  
! @@EndOfTable:   cmp     dx,-1                   ;did we exhaust the table?
                  je      @@Done                  ;yes, quit
                  mov     bx,dx                   ;bx = highest priority item
                  cmp     es:[bx.calltype],PNEAR  ;is it near or far?

-- 
Chin Huang  cthuang@zerosan.UUCP  chin.huang@canrem.com