comp.lang.ada
 help / color / mirror / Atom feed
From: "Robert I. Eachus" <rieachus@attbi.com>
Subject: Re: How to Emulate C++ Macro with Static Local Variable?
Date: Wed, 24 Sep 2003 23:44:21 GMT
Date: 2003-09-24T23:44:21+00:00	[thread overview]
Message-ID: <3F722C53.9020808@attbi.com> (raw)
In-Reply-To: ullsdvo26.fsf@sandia.gov

taashlo@sandia.gov wrote:
> Hello,
> 
> I'm trying to port a small C++ library to Ada95.  Most of it is going
> quite well in that the Ada implementation is smaller, simpler, and
> easier to follow than the C++ implementation.  But I've ran into a
> hurdle with the following C++ construction:
> 
> class Test {
> ...
> protected:
>    struct s {
>       int data[8];
>    };
> ...
>    void bar(s *t, int foo);
>    #define BAR(foo_) if (1) { \
>       static s t_; \
>       bar(&t_, foo_);\
>    } else ((void)0)
> ...
> };
> 
> What happens is that when you do this:
> 
> BAR(10);
> 
> it expands to this:
> 
> if (1) {
>   static s t_;
>   bar(&t_, 10);
> } else ((void)0);
> 
> This, in effect, creates a (hidden) static local variable for each call
> to bar().  This static variable (actually a structure, t_) is used to
> cache information for each unique call to bar() such that subsequent
> calls from that location can be processed *much* faster.
> 
> For instance, the following code would create three of the hidden local
> variables:
> 
> for (int i = 0; i < 55; ++i) {
>    switch (wozit()) {
>       case 1: BAR(10); break;
>       case 2: BAR(20); break;
>       case 3: BAR(30); break;
>    }
> }
> 
> The first time each BAR() is encountered, it does the full processing,
> but subsequent calls to the *same* BAR() used it's unique cached
> information and go much faster.
> 
> Any ideas on how I can achieve this with Ada95?

Wild, I'm going to give you "ideas," and let you implement one of them.

First, the normal way to implement this in Ada would be to break the 
action into a generic instantiation followed by a call of the 
instantiated generic.  But if you want to follow that pattern here it 
gets tricky to wrap it in a generic.  You would need a subprogram access 
type declared at an outer level, the generic instantiation would create 
a procedure and pass back the access value for subsequent calls.

The fast way to implement this of course is to use self-modifying code. 
  Ugh!  You can manage this with subprogram parameters.  The first call 
goes to the 'generic' version which returns among other things the new 
address to call.  Sort of:

procedure Subp is

   type Subprogram_Record;

   type Subprogram_Pointer is
        access procedure(X: in Integer; P: in out Subprogram_Record);

   type Subprogram_Record is record
     SP: Subprogram_Pointer;
   end record;

   procedure Test (X: in Integer; P: in out Subprogram_Record)
   is begin null; end;

   Bar_Pointer: constant Subprogram_Record := (SP => Test'Access);

   Local_Pointer: Subprogram_Record := Bar_Pointer;
begin
   Local_Pointer.SP.all(3, Local_Pointer);
end Subp;

This code is a bit ugly, but it does compile.  And since Bar_Pointer is 
a constant, you can't accidently pass it to Test.  There might be a 
cleaner cleverer way to do it, but this works.

The cleanest option may be to run your code through a preprocessor and 
use a similar macro.

-- 
                                                        Robert I. Eachus

Ryan gunned down the last of his third white wine and told himself it 
would all be over in a
few minutes.  One thing he'd learned from Operation Beatrix: This field 
work wasn't for him. --from Red Rabbit by Tom Clancy.




  reply	other threads:[~2003-09-24 23:44 UTC|newest]

Thread overview: 28+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2003-09-24 22:06 How to Emulate C++ Macro with Static Local Variable? taashlo
2003-09-24 23:44 ` Robert I. Eachus [this message]
2003-09-25  3:27   ` Hyman Rosen
2003-09-25  4:53     ` tmoran
2003-09-25 15:57       ` Robert I. Eachus
2003-09-25 19:09         ` tmoran
2003-09-29 14:57           ` taashlo
2003-09-29 18:12             ` Jeffrey Carter
2003-09-29 18:51               ` taashlo
2003-09-30  1:32                 ` Jeffrey Carter
2003-09-30  1:54                   ` tmoran
2003-09-30 13:02                   ` taashlo
2003-09-30 20:25                     ` Jeffrey Carter
2003-09-30  2:45             ` Robert I. Eachus
2003-09-30  3:24               ` tmoran
2003-09-25 13:43     ` Stephen Leake
2003-09-25 12:59   ` Tad Ashlock
2003-09-25 16:11     ` Robert I. Eachus
2003-09-25 18:13       ` Randy Brukardt
2003-09-25 23:40         ` Robert I. Eachus
2003-09-25 11:54 ` Gautier
2003-09-25 16:14   ` Robert I. Eachus
2003-09-25 18:06   ` Tad Ashlock
2003-09-28  8:42     ` Gautier Write-only
2003-09-28 20:06       ` Jeffrey Carter
2003-09-29  2:13         ` Gautier Write-only
2003-09-25 13:41 ` Stephen Leake
2003-09-25 17:23   ` Tad Ashlock
replies disabled

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox