Eiffel "Gotchas"

07 April 1998


Gotcha #8 - Answer and Explanation

Here's the question again:

In what context will a routine containing this declaration

   local
      a: A
      b: B

behave differently at runtime from the same routine with the order of declaration reversed:

   local
      b: B
      a: A

The "gotcha" comes from the fact that a local entity may be expanded, in which case the creation routine (if any) will be automatically executed upon routine entry.

If we assume that local entities are initialized in order of declaration (an assumption that may be compiler-dependent), we can construct this system which executes to completion as shown, but fails ("feature call on void reference") if the order of declaration of 'a' and 'b' is reversed.

This is because when 'a' is declared first, the once-function is primed to always return the string "gotcha", so the call to 'to_upper' succeeds in both A and B. When 'b' is declared first, the once-function is primed to always return a void reference, so the call to 'to_upper' will fail in B (and would also fail in A if execution got that far).

   class MAIN
   creation make
   feature
      make is
         local
            a: A
            b: B
         do
         end
   end

   expanded class A
   inherit SHARED_ONCE_FUNCTION
   creation make
   feature
      make is
         do
            once_function("gotcha").to_upper
         end
   end

   expanded class B
   inherit SHARED_ONCE_FUNCTION
   creation make
   feature
      make is
         do
            once_function(void).to_upper -- fails if 'b' decleared before 'a'
         end
   end

   class SHARED_ONCE_FUNCTION
   feature
      once_function(argument: STRING): STRING is
         once
            result := argument
         end
   end

Thanks to Alexei Kanatov of SIG Moscow for suggesting this one.


Eiffel and NICE are registered trademarks of the Nonprofit International Consortium for Eiffel.

Eiffel "Gotchas"