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.
next prev parent 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