CVS difference for ais/ai-00366.txt
--- ais/ai-00366.txt 2004/01/08 04:15:32 1.1
+++ ais/ai-00366.txt 2004/02/04 00:51:14 1.2
@@ -65,4 +65,97 @@
!appendix
+From: Randy Brukardt
+Sent: Tuesday, February 3, 2004 5:16 PM
+
+In the context of AI-362, I was thinking about how to get any sort of
+logging/debugging into a Preelaborated unit.
+
+The problem is that once a preelaborated unit has that pragma applied, you can
+no longer with any I/O. Without I/O, you can't have any logging for faults in a
+fielded system (if the system dies, it probably won't get to dump an in-memory
+log, making it useless for field debugging - you probably can't run a debugger
+on the target system - think about NASA's rovers...)
+
+I realized that something that my spam filter's code does provides a solution
+(assuming some up-front work):
+
+ package Something is
+ pragma Preelaborate (Something);
+ type Logger_Access is access procedure (Text : in String);
+
+ procedure Do_Something (....; Logger : Logger_Access := null);
+ end Something;
+
+Then, a call to Do_Something can include a logger, even if the logger couldn't
+be withed by the Preelaborated unit:
+ Do_Something (...., Logger => Ada.Text_IO.Put_Line'Access);
+
+If you do this consistently, with each preelaborated routine passing the logger
+on through any calls, you can pretty much log anything you need in a
+preelaborated unit. At the cost of an extra parameter to everything, of course.
+(You could use a global variable as well, but that's UGLY!)
+
+That's OK for preelaborated units, since that is mainly about library-level
+elaboration: which necessarily has been completed before any call can be made.
+
+However, AI-366 proposes to allow access-to-subprogram and
+access-to-object-with-empty-pool in pure units. This means that it would be
+trivial to pass an impure function to a Pure function, and thus make the
+results vary even if the parameters are the same (as per the permission of
+10.2.1(18)):
+
+ package Impure is
+ pragma Pure (Impure);
+ type Random_Access is function return Float;
+
+ function Use_Random (Random : in Random_Access) return Natural;
+
+ end Impure;
+
+ A := Use_Random (Random'Access);
+ B := Use_Random (Random'Access);
+
+Clearly, the calls to Use_Random have the same values for a by-copy parameter,
+but A and B are unlikely to have the same values. Yet the compiler can omit the
+second call.
+
+Indeed, this permission allows me to write a "Pure" random number generator:
+
+ package Pure_Random is
+ pragma Pure (Pure_Random);
+ type Generator is private;
+ type Generator_Access is access all Generator;
+ for Generator_Access'Storage_Size use 0;
+
+ function Random (Gen : in Generator_Access) return Float;
+ end Pure_Random;
+
+ Gen : aliased Pure_Random.Generator;
+
+ A := Pure_Random.Random (Gen'Access);
+ B := Pure_Random.Random (Gen'Access);
+
+Clearly, the permission of 10.2.1(18) applies to these calls, and yet it
+clearly must not!
+
+So it appears that AI-366 is incomplete, in that it should address this issue
+somehow.
+
+We'd really rather not allow such functions as Pure -- but that's the current
+state; we could vote this AI No Action, but that's hardly responsive to the
+problem.
+
+One possibility is to do as the GNAT Pure_Function pragma, which is to say that
+pragma Pure is an assertion that any functions always return the (logically)
+same results and have no significant side-effects (without checking those
+assertions). In which case, we can leave the permission alone.
+
+But others have suggested that the permission of 10.2.1(18) is flawed anywhy
+(that discussion was filed in AI-290 about pragma Pure_Function). Perhaps the
+permission can be 'patched up' by including the values of access-to-object
+parameters, and excluding the permission if there are any access-to-subprogram
+parameters. (That's probably a bit too strong, but I'd rather err on the side
+of correctness rather than optimization...)
+
****************************************************************
Questions? Ask the ACAA Technical Agent