Topic
26 replies Latest Post - ‏2012-04-18T22:51:14Z by SystemAdmin
SystemAdmin
SystemAdmin
3180 Posts
ACCEPTED ANSWER

Pinned topic Function pointers

‏2012-04-12T09:02:05Z |

Dear all,

I try to make a function pointer, here is some sample code:
 

struct Toto {}
 
void titi(Toto toto, int b){
    void fptr(Toto toto, int b);
}
 
void tutu(Toto toto, int b){
        titi(toto,b)
}

 


This generates the following warnings at execution:

 

 

 

-W- DXL: <addins/user/temp.dxl:11> Le paramètre de fonction a nommé le paramètre (119348960)
Inclus à partir de :
    <Line:1> 
-W- DXL: <addins/user/temp.dxl:11> Le paramètre de fonction a nommé le paramètre (83520656)
Inclus à partir de :
        <Line:1> 
-I- DXL: Terminé. Erreurs signalées : 0. Avertissements signalés : 2.



I would like to know whether those warnings are errors or not, and if not whether it is possible to have some pragma to deactivate locally the warning generation.



 

 

Updated on 2014-01-06T19:55:38Z at 2014-01-06T19:55:38Z by iron-man
  • SystemAdmin
    SystemAdmin
    3180 Posts
    ACCEPTED ANSWER

    Re: Function pointers

    ‏2012-04-12T18:51:26Z  in response to SystemAdmin

    I'm a little rusty on my French, but some subset of the below should get you going:
     

    // Function Fun
     
    /*
      Function Fun
    */
     
     
    int* PtrOps_intStarAddressOf(_m &v) {
        int *val = &(addr_ (int (addr_ (v))));
        return (val);
    }
     
    int PtrOps_addressOfVar(_m& anyVar) {
        int temp = (int addr_ PtrOps_intStarAddressOf(anyVar));
        return temp;
    }
     
    int PtrOps_internalIntContentOfAddress(int& refToInt) {
        int content = refToInt;
        return content;
    }
     
    int PtrOps_intContentOfAddress(int address) {
        return (PtrOps_internalIntContentOfAddress(addr_ address));
    }
     
     
    int PtrOps_addressOfVoidFunctionWithNoParameterHelper(int dummyParameterOne, void function()) {
        int addressOfParameterOne;
        int contentOfParameterOne;
     
        int addressOfParameterTwo;
        int contentOfParameterTwo;
     
        addressOfParameterOne = PtrOps_addressOfVar(dummyParameterOne);
        contentOfParameterOne = PtrOps_intContentOfAddress(addressOfParameterOne);
     
        //--------------------------------------------------------------------------
        // DOORS blows up if you get the address of "void function(void)" function
        // directly.  Alternate approach:
        // 1) Pass in a dummy int parameter prior to the function parameter.
        // 2) Figure out the address of the dummy parameter.
        // 3) We know the temperamental function parameter content is 4 bytes ahead
        //    of the dummy address.
        // 4) Look four bytes ahead and extract an int that lies there.
        // 5) Done
        //--------------------------------------------------------------------------
     
        addressOfParameterTwo = addressOfParameterOne + 4;
        contentOfParameterTwo = PtrOps_intContentOfAddress(addressOfParameterTwo);
     
        return contentOfParameterTwo;
    }
     
    int PtrOps_addressOfVoidFunctionWithNoParameter(void function()) {
        int dummyParameterOne = 1111;
        return PtrOps_addressOfVoidFunctionWithNoParameterHelper(dummyParameterOne, function);
    }
     
    int PtrOps_addressOfVoidFunctionWithOneNonRefParameter(void function(_m)) {
        return (int (addr_ function));
    }
     
    void callNoParameterVoidFunction(void function()) {
        function();
    }
     
    void callOneParameterVoidFunction(void function(_m)) {
        function("one");
    }
     
    void oneParameter(string msg) {
        print ">>> Hello from void function with " msg " parameter! <<<\n";
    }
     
    void noParameter() {
        print ">>> Hello from void function with no parameter! <<<\n";
    }
     
    void addressOfFunctionDemo() {
        print("I'm calling a one parameter void function directly\n");
        oneParameter("one");
        print("I'm calling a no parameter void function directly\n");
        noParameter();
     
        print("\n");
     
        print("I'm calling a one parameter void function by passing function by typed-function signature\n");
        callOneParameterVoidFunction( oneParameter );
        print("I'm calling a no parameter void function by passing function by typed-function signature\n");
        callNoParameterVoidFunction( noParameter );
     
        print("\n");
     
        int addressOfVoidFunctionWithOneNonRefParameter = PtrOps_addressOfVoidFunctionWithOneNonRefParameter( oneParameter );
        int addressOfVoidFunctionWithNoParameter = PtrOps_addressOfVoidFunctionWithNoParameter( noParameter );
     
        print("The address of a one parameter void function is (in decimal) " (addressOfVoidFunctionWithOneNonRefParameter) "\n");
        print("The address of a no parameter void function is (in decimal) " (addressOfVoidFunctionWithNoParameter) "\n");
     
        print("\n");
     
        print("I'm calling a one parameter void function by hacking-in the address\n");
        callOneParameterVoidFunction( addr_ addressOfVoidFunctionWithOneNonRefParameter );
     
        print("I'm calling a no parameter void function by hacking-in the address\n");
        callNoParameterVoidFunction( addr_ addressOfVoidFunctionWithNoParameter );
    }
     
    addressOfFunctionDemo();
    
    Updated on 2014-01-06T19:56:36Z at 2014-01-06T19:56:36Z by iron-man
    • SystemAdmin
      SystemAdmin
      3180 Posts
      ACCEPTED ANSWER

      Re: Function pointers

      ‏2012-04-13T15:11:43Z  in response to SystemAdmin

      Hello,

      This is very strange, because what you propose almost work, but I get some access violation error, here is my sample code:
       

      struct Toto {}
       
      int handlerAddress(void handler(Toto toto, int b)){
          return (addr_ handler) int
      }
       
      void callHandler(void handler(Toto toto, int b), Toto toto, int b){
              handler(toto, b)
      }
       
      Array handlerList = create(2,1);
       
      void handler0(Toto toto, int b){
              print "\n---------------------------\nThis is handler0\n---------------------------"
      }
      put(handlerList, handlerAddress(handler0), 0, 0)
       
      void handler1(Toto toto, int b){
              print "\n---------------------------\nThis is handler1\n---------------------------"
      }
       
      put(handlerList, handlerAddress(handler1), 1, 0)
       
       
      void noAccessViolation(Toto toto, int b){
              int fptr = handlerAddress(handler0)
              callHandler( addr_ fptr, toto, b)
       
              fptr = handlerAddress(handler1)
              callHandler( addr_ fptr, toto, b)
      }
       
       
      void accessViolation(Toto toto, int b){
              int fptr = get(handlerList, 0, 0);
              callHandler( addr_ fptr, toto, b)
       
              fptr = get(handlerList, 1, 0);
              callHandler( addr_ fptr, toto, b)
       
      }
       
      Toto createToto(){
              Array this = create(10,1)
              return (addr_ this) Toto
      }
       
      void deleteToto(Toto toto){
              Array this = (addr_ toto) Array
              delete  this
      }
       
       
      Toto dummy = createToto
       
      noAccessViolation(dummy, 0)
      accessViolation(dummy, 0)
       
      deleteToto dummy
      delete handlerList
      

       


      The call to noAccessViolation works fine, but the call to accessViolation breaks with an access violation error between the call to handler0 and the call to handler1. Here is what I get:

       

       

       

      -W- DXL: <Line:4> Le paramètre de fonction a nommé le paramètre (119348960)
      -W- DXL: <Line:4> Le paramètre de fonction a nommé le paramètre (83520656)
      -W- DXL: <Line:8> Le paramètre de fonction a nommé le paramètre (119348960)
      -W- DXL: <Line:8> Le paramètre de fonction a nommé le paramètre (83520656)
      -I- DXL: Terminé. Erreurs signalées : 0. Avertissements signalés : 4.
       
      ---------------------------
      This is handler0
      ---------------------------
      ---------------------------
      This is handler1
      ---------------------------
      ---------------------------
      This is handler0
      ----------------------------R-E- DXL: <Line:39> Une erreur inattendue s'est produite : doors.exe caused an EXCEPTION_ACCESS_VIOLATION in module doors.exe at 001B:009050BD
       
      Traçage :
          <Line:58> 
      -R-F- DXL: <Line:39> Erreur interne, soumettez un rapport de bogue
      Traçage :
              <Line:58> 
      -I- DXL: Exécution arrêtée
      

       

       

      Updated on 2014-01-06T19:58:43Z at 2014-01-06T19:58:43Z by iron-man
      • SystemAdmin
        SystemAdmin
        3180 Posts
        ACCEPTED ANSWER

        Re: Function pointers

        ‏2012-04-13T17:55:31Z  in response to SystemAdmin

        I found two problems:
         

        • In parameter lists where the parameter is a function and the function has arguments, you just put in the types of the arguments.
        • Unless you are feeling extremely lucky, ALWAYS cast when extracting data from one of DXL's flexible objects (e.g., Array, Skip, etc.)


        Here is a repaired version of your code:

         

         

        // Desmond Toto
         
        /*
          Desmond Toto
        */
         
         
        struct Toto {}
         
        // Global ...
        Array handlerList;
        Toto dummy;
        // ... end global
         
        void handler0(Toto toto, int b){
            print "\n---------------------------\nThis is handler0\n---------------------------\n"
        }
         
        void handler1(Toto toto, int b){
            print "\n---------------------------\nThis is handler1\n---------------------------\n"
        }
         
         
        int handlerAddress(void handler(Toto, int)){
            return (addr_ handler) int
        }
         
        void callHandler(void handler(Toto, int), Toto toto, int b){
            handler(toto, b)
        }
         
        void noAccessViolation(Toto toto, int b){
            int fptr = handlerAddress(handler0)
            print("fptr = " (fptr) "\n");
            callHandler( addr_ fptr, toto, b)
         
            fptr = handlerAddress(handler1)
            print("fptr = " (fptr) "\n");
            callHandler( addr_ fptr, toto, b)
        }
         
        void accessViolation(Toto toto, int b){
            int fptr = (int get(handlerList, 0, 0));
            print("fptr = " (fptr) "\n");
            callHandler( addr_ fptr, toto, b)
            //--------------------------------------------------------------------------
            // If you remove the (int) cast below you'll be in trouble
            // DXL will let you shot youself in the foot
            // ALWAYS cast when extracting data from Array, Skip, etc. to be safe
            //--------------------------------------------------------------------------
            fptr = (int get(handlerList, 1, 0));
            print("fptr = " (fptr) "\n");
            callHandler( addr_ fptr, toto, b)
        }
         
        Toto createToto(){
            return (Toto addr_ (Array create(10,1)) )
        }
         
        void deleteToto(Toto toto){
            Array this = (addr_ toto) Array
            delete  this
        }
         
        void showArray(Array a) {
            print("a[0][0] = " (int get(a, 0, 0)) "\n");
            print("a[0][1] = " (int get(a, 1, 0)) "\n");
            print("handler0 = " (int addr_ handler0) "\n");
            print("handler1 = " (int addr_ handler1) "\n");
        }
         
         
        void main() {
            handlerList = create(2,1);
            put(handlerList, handlerAddress(handler0), 0, 0)
            put(handlerList, handlerAddress(handler1), 1, 0)
            showArray(handlerList);
            dummy = createToto
            noAccessViolation(dummy, 0)
            accessViolation(dummy, 0)
            deleteToto dummy
            delete handlerList
        }
         
        main();
        



        OUTPUT:
        a[0][0] = 153276328
        a[0][1] = 153276352
        handler0 = 153276328
        handler1 = 153276352
        fptr = 153276328



         

         

         

         


        This is handler0

         

         

         


        fptr = 153276352

         

         

         


        This is handler1

         

         

         


        fptr = 153276328

         

         

         


        This is handler0

         

         

         


        fptr = 153276352

         

         

         


        This is handler1

         

         

         


         

        Updated on 2014-01-06T19:59:55Z at 2014-01-06T19:59:55Z by iron-man
  • adevicq
    adevicq
    154 Posts
    ACCEPTED ANSWER

    Re: Function pointers

    ‏2012-04-13T07:24:33Z  in response to SystemAdmin

    Bonjour,

    Here is an example of function pointers:
     

    void fCalled(int i, string s) {
    ...
    }
     
    // declare your function as a parameter without naming the functions' parameters
    void fMain(int a, void f(int, string)) {
    string b="toto"
    ...
    f(a, b)
    }
     
    // call the function with the name of the called function...
    fMain(12, fCalled)
    

     


    Is it what you're looking for?
    Cordialement,

    Alain

     

    Updated on 2014-01-06T20:01:21Z at 2014-01-06T20:01:21Z by iron-man
  • SystemAdmin
    SystemAdmin
    3180 Posts
    ACCEPTED ANSWER

    Re: Function pointers

    ‏2012-04-13T09:05:55Z  in response to SystemAdmin

    You are missing the body of your nested function

    struct Toto {}
     
    void titi(Toto toto, int b){
        void fptr(Toto toto, int b) {
            };
    }
     
    void tutu(Toto toto, int b){
            titi(toto,b)
    }
    


    Adam

    Updated on 2014-01-06T20:02:00Z at 2014-01-06T20:02:00Z by iron-man
    • SystemAdmin
      SystemAdmin
      3180 Posts
      ACCEPTED ANSWER

      Re: Function pointers

      ‏2012-04-13T14:28:57Z  in response to SystemAdmin

      No this is not what I was looking for. If you
       

      void titi(Toto toto, int b){
          void fptr(Toto toto, int b) {
              };
       
       
      }
      
      Updated on 2014-01-06T20:02:31Z at 2014-01-06T20:02:31Z by iron-man
      • SystemAdmin
        SystemAdmin
        3180 Posts
        ACCEPTED ANSWER

        Re: Function pointers

        ‏2012-04-13T14:35:59Z  in response to SystemAdmin

        Sorry, for some reason my previous message was posted before I could complete it.
        No this is not what I was looking for, because fptr cannot be modified with you suggestion. If I do this:
         

        void tutu(int a, int b){
          
           print "Hello"
         
        }
         
         
        void doit(){
            void fptr(int a, int b) {
                };
         
              fptr = tutu
         
                fptr(0, 0);
         
        } 
         
        doit
        

         


        Then I get the error:

         

         

         

        -E- DXL: <Line:13> Utilisation incorrecte de l'identificateur (fptr)
        -I- DXL: Terminé. Erreurs signalées : 1. Avertissements signalés : 0.
        



        But I think that I can find some solution using some other of the answers.

        Vincent.



         

         

        Updated on 2014-01-06T20:03:39Z at 2014-01-06T20:03:39Z by iron-man
        • SystemAdmin
          SystemAdmin
          3180 Posts
          ACCEPTED ANSWER

          Re: Function pointers

          ‏2012-04-13T15:02:24Z  in response to SystemAdmin

          Not sure I understand what you want...

          Maybe this??

          void tutu(int a, int b)
          {
              print("Hello, a=" a ", b=" b "\n")
          }
           
           
          void doit(void aFunction(int, int))
          {
                  aFunction(1, 2);
          } 
           
          doit(tutu)
          


          Adam

          Updated on 2014-01-06T20:04:36Z at 2014-01-06T20:04:36Z by iron-man
        • Mathias Mamsch
          Mathias Mamsch
          1936 Posts
          ACCEPTED ANSWER

          Re: Function pointers

          ‏2012-04-16T09:37:12Z  in response to SystemAdmin
          Hi Vicent,

          if you are asking about storing a function in a variable and calling it, look at the following post:

          https://www.ibm.com/developerworks/forums/thread.jspa?messageID=14635624&#14635624

          Its basically the same as hal wrote, just shorter and it contains two helpers to set and call the stored function pointer to hide the implementation details from the caller. Maybe that helps, regards, Mathias


          Mathias Mamsch, IT-QBase GmbH, Consultant for Requirement Engineering and D00RS
          • SystemAdmin
            SystemAdmin
            3180 Posts
            ACCEPTED ANSWER

            Re: Function pointers

            ‏2012-04-16T12:46:57Z  in response to Mathias Mamsch
            Thanks,

            This is basically that type of thing which I got to after boiling down the code supplied by Fu Lin Yiu. For your information I am rather reading the function pointers from an Array than from a static variable. This is because what I am trying to do is an abstract interface (something that is natively supported in Java, and almost natively supported in C++). The idea is that I have a set of "interface" functions to which I pass some object that contains some array containing the pointers of the respective "implementation" of those interface functions.

            If you are familiar with Java or C++ you can certainly clearly understand what I mean.

            VBR,
            Vincent.
            • SystemAdmin
              SystemAdmin
              3180 Posts
              ACCEPTED ANSWER

              Re: Function pointers

              ‏2012-04-16T19:56:10Z  in response to SystemAdmin
              With regard to your desire to publish an interface that modules must implement (like in java), I know exactly what you mean and agree it is useful but could not find a way to formally enforce it using DXL.

              I while back I tried specifying a header file that a participating module must implement.

              I was hoping for a compilation error if methods were not implemented but DXL allows you to declare method signatures and does not care if they are not implemented.

              You can publish an interface, but it is only a "gentleman's agreement" serving to document your desire. You won't get DXL complaints if the interface is not fulfilled by a module that #includes it.

              I filed it in the "not worth the grief" folder. If you find a way to do this without making an un-natural programming model let us know.
              • SystemAdmin
                SystemAdmin
                3180 Posts
                ACCEPTED ANSWER

                Re: Function pointers

                ‏2012-04-17T07:26:46Z  in response to SystemAdmin

                Dear Fu Lin,

                DXL supports overloading, but you don't have natively the notion of objects, nor virtual methods. What I mean is that if I have some class
                 

                struct Toto {}
                

                 


                which serves the purpose of being an interface, and I have one method:

                 

                 

                 

                void mymethod(Toto toto) // virtual method
                { 
                   /* ...  here I do the call to the derived class method implementing void mymethod(Toto toto), I do that by some explicit code because DXL 
                       does not support natively virtual method ... */
                }
                


                And I have two derived classes

                 

                 

                 

                 

                struct Titi {} // implements Toto
                



                and



                 

                 

                 

                 

                struct Tutu {} // implements Toto
                



                with corresponding interface implementation of mymethod:



                 

                 

                 

                 

                void mymethod(Titi titi){
                   /* ...  here I do the the actual implementation void mymethod(Toto toto) according to Titi derivation ... */
                }
                 
                void mymethod(Tutu tutu){
                   /* ...  here I do the the actual implementation void mymethod(Toto toto) according to Tutu derivation ... */
                }
                



                What I mean by that there is no native vitual method, is that I need some explicit code inside ``void mymethod(Toto toto)'' to call either ``void mymethod(Titi titi)'' or ``void mymethod(Tutu tutu)'' when ``void mymethod(Toto toto)'' is called. Anyway DXL does not allow to declare that Titi and Tutu are derived from Toto, there is no keywords to declare that, once again everything relies on some explicit coding.

                Concerning your statement "without making an un-natural programming model" I am not sure to understand what you mean. What I am doing is "un-native" because DXL does not support it natively. It is just like if you made objects and classes with Assembler or with C, you need to implement by hand all the derivation and indirection machinery, and some sort of symbol decoration --- which DXL has natively ---, without the help of the compiler. However, it is not "un-natural", because it just follows the same concepts and techniques that C++ and Java support natively.

                Vincent.

                PS-1: BTW, is it correct that "Fu Lin" is your forename and "Yiu" your surname?
                PS-2: Please ignore the sequel: =test 1= /test 2/



                 

                 

                Updated on 2014-01-06T20:07:22Z at 2014-01-06T20:07:22Z by iron-man
              • SystemAdmin
                SystemAdmin
                3180 Posts
                ACCEPTED ANSWER

                Re: Function pointers

                ‏2012-04-17T07:28:17Z  in response to SystemAdmin

                Dear Fu Lin,

                DXL supports overloading, but you don't have natively the notion of objects, nor virtual methods. What I mean is that if I have some class
                 

                struct Toto {}
                

                 


                which serves the purpose of being an interface, and I have one method:

                 

                 

                 

                void mymethod(Toto toto) // virtual method
                { 
                   /* ...  here I do the call to the derived class method implementing void mymethod(Toto toto), I do that by some explicit code because DXL 
                       does not support natively virtual method ... */
                }
                


                And I have two derived classes

                 

                 

                 

                 

                struct Titi {} // implements Toto
                



                and



                 

                 

                 

                 

                struct Tutu {} // implements Toto
                



                with corresponding interface implementation of mymethod:



                 

                 

                 

                 

                void mymethod(Titi titi){
                   /* ...  here I do the the actual implementation void mymethod(Toto toto) according to Titi derivation ... */
                }
                 
                void mymethod(Tutu tutu){
                   /* ...  here I do the the actual implementation void mymethod(Toto toto) according to Tutu derivation ... */
                }
                



                What I mean by that there is no native vitual method, is that I need some explicit code inside ``void mymethod(Toto toto)'' to call either ``void mymethod(Titi titi)'' or ``void mymethod(Tutu tutu)'' when ``void mymethod(Toto toto)'' is called. Anyway DXL does not allow to declare that Titi and Tutu are derived from Toto, there is no keywords to declare that, once again everything relies on some explicit coding.

                Concerning your statement "without making an un-natural programming model" I am not sure to understand what you mean. What I am doing is "un-native" because DXL does not support it natively. It is just like if you made objects and classes with Assembler or with C, you need to implement by hand all the derivation and indirection machinery, and some sort of symbol decoration --- which DXL has natively ---, without the help of the compiler. However, it is not "un-natural", because it just follows the same concepts and techniques that C++ and Java support natively.

                Vincent.

                PS-1: BTW, is it correct that "Fu Lin" is your forename and "Yiu" your surname?
                PS-2: Please ignore the sequel: =test 1= /test 2/



                 

                 

                Updated on 2014-01-06T20:11:55Z at 2014-01-06T20:11:55Z by iron-man
              • SystemAdmin
                SystemAdmin
                3180 Posts
                ACCEPTED ANSWER

                Re: Function pointers

                ‏2012-04-17T07:29:11Z  in response to SystemAdmin

                Dear Fu Lin,

                DXL supports overloading, but you don't have natively the notion of objects, nor virtual methods. What I mean is that if I have some class
                 

                struct Toto {}
                

                 


                which serves the purpose of being an interface, and I have one method:

                 

                 

                 

                void mymethod(Toto toto) // virtual method
                { 
                   /* ...  here I do the call to the derived class method implementing void mymethod(Toto toto), I do that by some explicit code because DXL 
                       does not support natively virtual method ... */
                }
                


                And I have two derived classes

                 

                 

                 

                 

                struct Titi {} // implements Toto
                



                and



                 

                 

                 

                 

                struct Tutu {} // implements Toto
                



                with corresponding interface implementation of mymethod:



                 

                 

                 

                 

                void mymethod(Titi titi){
                   /* ...  here I do the the actual implementation void mymethod(Toto toto) according to Titi derivation ... */
                }
                 
                void mymethod(Tutu tutu){
                   /* ...  here I do the the actual implementation void mymethod(Toto toto) according to Tutu derivation ... */
                }
                



                What I mean by that there is no native vitual method, is that I need some explicit code inside ``void mymethod(Toto toto)'' to call either ``void mymethod(Titi titi)'' or ``void mymethod(Tutu tutu)'' when ``void mymethod(Toto toto)'' is called. Anyway DXL does not allow to declare that Titi and Tutu are derived from Toto, there is no keywords to declare that, once again everything relies on some explicit coding.

                Concerning your statement "without making an un-natural programming model" I am not sure to understand what you mean. What I am doing is "un-native" because DXL does not support it natively. It is just like if you made objects and classes with Assembler or with C, you need to implement by hand all the derivation and indirection machinery, and some sort of symbol decoration --- which DXL has natively ---, without the help of the compiler. However, it is not "un-natural", because it just follows the same concepts and techniques that C++ and Java support natively.

                Vincent.

                PS-1: BTW, is it correct that "Fu Lin" is your forename and "Yiu" your surname?
                PS-2: Please ignore the sequel: =test 1= /test 2/



                 

                 

                Updated on 2014-01-06T20:14:18Z at 2014-01-06T20:14:18Z by iron-man
              • SystemAdmin
                SystemAdmin
                3180 Posts
                ACCEPTED ANSWER

                Re: Function pointers

                ‏2012-04-17T07:39:24Z  in response to SystemAdmin

                Dear Fu Lin,

                DXL supports overloading, but you don't have natively the notion of objects, nor virtual methods. What I mean is that if I have some class
                 

                struct Toto {}
                

                 


                which serves the purpose of being an interface, and I have one method:

                 

                 

                 

                void mymethod(Toto toto) // virtual method
                { 
                   /* ...  here I do the call to the derived class method implementing void mymethod(Toto toto), I do that by some explicit code because DXL 
                       does not support natively virtual method ... */
                }
                


                And I have two derived classes

                 

                 

                 

                 

                struct Titi {} // implements Toto
                



                and



                 

                 

                 

                 

                struct Tutu {} // implements Toto
                



                with corresponding interface implementation of mymethod:



                 

                 

                 

                 

                void mymethod(Titi titi){
                   /* ...  here I do the the actual implementation void mymethod(Toto toto) according to Titi derivation ... */
                }
                 
                void mymethod(Tutu tutu){
                   /* ...  here I do the the actual implementation void mymethod(Toto toto) according to Tutu derivation ... */
                }
                



                What I mean by that there is no native vitual method, is that I need some explicit code inside ``void mymethod(Toto toto)'' to call either ``void mymethod(Titi titi)'' or ``void mymethod(Tutu tutu)'' when ``void mymethod(Toto toto)'' is called. Anyway DXL does not allow to declare that Titi and Tutu are derived from Toto, there is no keywords to declare that, once again everything relies on some explicit coding.

                Concerning your statement "without making an un-natural programming model" I am not sure to understand what you mean. What I am doing is "un-native" because DXL does not support it natively. It is just like if you made objects and classes with Assembler or with C, you need to implement by hand all the derivation and indirection machinery, and some sort of symbol decoration --- which DXL has natively ---, without the help of the compiler. However, it is not "un-natural", because it just follows the same concepts and techniques that C++ and Java support natively.

                Vincent.

                PS-1: BTW, is it correct that "Fu Lin" is your forename and "Yiu" your surname?
                PS-2: Please ignore the sequel: =test 1= /test 2/



                 

                 

                Updated on 2014-01-06T20:16:56Z at 2014-01-06T20:16:56Z by iron-man
                • Mathias Mamsch
                  Mathias Mamsch
                  1936 Posts
                  ACCEPTED ANSWER

                  Re: Function pointers

                  ‏2012-04-17T11:04:37Z  in response to SystemAdmin

                  Ok, Maybe you are moving into being more object oriented? If you wanted to have "virtual functions" and inheritance from a Base class you would do something like this in DXL:
                   

                  struct Base {}
                   
                  // constructor & destructor for Base
                  Base createBase_ () { DxlObject dx = new; Base x = (addr_ dx) Base; return x}
                  DxlObject DxlObjectOf (Base x) { return ((addr_ x) DxlObject) }
                  void VirtualFunction_ (Base &x) { DxlObject dx = DxlObjectOf x; delete dx; x = null; }
                   
                  // virtual function VirtualFunction property:
                  void set_VirtualFunction (Base var, void func (Base &)) { (DxlObjectOf var)->"adVirtualFunction" = ((addr_ func) int) }
                  void call_VirtualFunction (void func (Base &), Base &this) { func( this ) }
                   
                  // virtual function VirtualFunction proxy:
                  void VirtualFunction (Base this) { 
                      if (null this) { return false }
                      int ad = ((DxlObjectOf this)->"adVirtualFunction") int 
                      if (ad != 0) call_VirtualFunction (addr_ ad,  this)
                      
                      VirtualFunction_ this
                  }
                   
                  struct Derived1 {}
                  Base super (Derived1 this) { return ((addr_ this) Base) }
                   
                   
                  struct Derived2 {}
                  Base super (Derived2 this) { return ((addr_ this) Base) }
                   
                  // virtual function VirtualFunction proxy:
                  void Derived1_VirtualFunction (Base &this) {
                      Base deref = this 
                      Derived1 mst = addr_ deref
                      print "Virtual Function of Derived1\n" 
                  }
                   
                   
                  Derived1 createDerived1 () {
                      Base st = createBase_()
                      Derived1 stMod = addr_ st 
                      set_VirtualFunction (st, Derived1_VirtualFunction)
                      return ((addr_ st) Derived1)
                  }
                   
                  // virtual function VirtualFunction proxy:
                  void Derived2_VirtualFunction (Base &this) {
                      Base deref = this 
                      Derived2 mst = addr_ deref
                      print "Virtual Function of Derived2\n" 
                  }
                   
                  Derived2 createDerived2 () {
                      Base st = createBase_()
                      Derived1 stMod = addr_ st 
                      set_VirtualFunction (st, Derived2_VirtualFunction)
                      return ((addr_ st) Derived2)
                  }
                   
                  // ---------------------snip end library code ----------------
                   
                   
                  Derived1 d1 = createDerived1()
                  VirtualFunction super d1   // call a base class function 
                   
                  Derived2 d2 = createDerived2()
                  VirtualFunction super d2   // call a base class function
                  

                   


                  This way you can have you base class with your virtual functions and your sweet functionality in your base class while the special implementation of the derived classes is completly hidden from the base class function. I used this method to implement a 'Storage' class with an interface to read a file, write a file, list files, create a directory, delete a directory, etc. Then I created derived classes for:

                   

                   

                  • The File System
                  • The DOORS Config Area
                  • A Memory Storage
                  • A DOORS Module (Using Hierarchy as Filesystem and an attribute as file contents)


                  Now I can write a File Explorer working on the Storage Base Class, and it will work for showing the contents of all the above. Or I could have a copy function to copy files from one Storage to Another, which will allow me to copy files from Config Area to File System, From File System to Memory, etc. That approach works really well.

                  Maybe that informations helps, regards, Mathias

                   

                   


                  Mathias Mamsch, IT-QBase GmbH, Consultant for Requirement Engineering and D00RS

                   

                  Updated on 2014-01-06T20:18:33Z at 2014-01-06T20:18:33Z by iron-man
                • SystemAdmin
                  SystemAdmin
                  3180 Posts
                  ACCEPTED ANSWER

                  Re: Function pointers

                  ‏2012-04-17T21:31:54Z  in response to SystemAdmin

                  Interfaces come in handy when you want to farm work out to a third party (or a co-worker) and you don't care about the implementation but want a standard interface.

                  In Java you can create (or reference) an interface and say (for example) your software product must implement Iterator for some object type.

                  See:
                  http://docs.oracle.com/javase/7/docs/api/java/util/Iterator.html

                  http://en.wikipedia.org/wiki/Iterator#Java

                  As an integrator of works from third parties and developers, the interface is handy because if the third parties said they would implement an interface but there is no body to correspond, it won't compile. In DXL one could #include the below but you would only know a member was not implemented if had code that called it.

                  Mapping to the DXL, I'd like to say "You must implement this:"
                   

                  // Suppose this is in "ThirdPartyIterator.inc" which is #included in the source module
                   
                  struct ThirdPartyObjectType {};
                   
                  // Returns true if the iteration has more elements.
                  boolean hasNext(ThirdPartyObjectType);
                   
                  // Returns the next element in the iteration.
                  ThirdPartyObjectType next(ThirdPartyObjectType);
                   
                  // Removes from the underlying collection the last element returned by this iterator // (optional operation).
                  void remove(ThirdPartyObjectType);
                  

                   


                  Other than calling them to see if they blow up, how could you get the DXL compiler tell you if hasNext() and next() were implemented per the interface contract?

                   

                  Updated on 2014-01-06T20:19:17Z at 2014-01-06T20:19:17Z by iron-man
                  • Mathias Mamsch
                    Mathias Mamsch
                    1936 Posts
                    ACCEPTED ANSWER

                    Re: Function pointers

                    ‏2012-04-18T13:09:37Z  in response to SystemAdmin
                    I would handle this more pragmatic. If I implemented an interface, I would try to create test code, that will perform a basic functionality test of the interface with all invariants (i.e. tests that should behave the same for all interface implementations). Instead of trying to get the DXL compiler to do stuff, if this is really important you should think about pimping your developer environment to perform things like that 'Interface Completeness' check. Once you run the code in your production environment, you probably should have checked completeness anyway. Virtual Functions in DXL allow the implementation of interfaces. Better to use them, then spending time on trying to transform DXL into Java. Just my two cents. Regards, Mathias

                    Mathias Mamsch, IT-QBase GmbH, Consultant for Requirement Engineering and D00RS
                    • SystemAdmin
                      SystemAdmin
                      3180 Posts
                      ACCEPTED ANSWER

                      Re: Function pointers

                      ‏2012-04-18T18:07:47Z  in response to Mathias Mamsch
                      Mathias, I'm not disputing your approach. I'm just pointing out to users that are used to C, C++, or Java that the DXL compiler does not have native support for interfaces in a simple manner as other languages do.

                      DXL newbies may think (as I did at first) that if you put a collection of function forward declarations in an #include file, the content of the #include file could serve as the "interface spec" and if each forward declaration was not realized somewhere an error would emerge.

                      I believe (going back a few years) in programming language C, if forward declarations are #included and corresponding function bodies are not found, you will get a linker error.

                      I'm just stating for the benefit of DXL newbies, that (unlike C) a forward declaration could exist and not be realized with a corresponding function body.

                      If code tries to call a function that does not have a function body, you'll get an error.

                      If code does not call a function that does not have a function body, there will be no complaints from DXL.

                      This characteristic of DXL is not typical of popular programming languages and I wrote up this statement of behavior so users won't have a surprise one day.
                      • llandale
                        llandale
                        2943 Posts
                        ACCEPTED ANSWER

                        Re: Function pointers

                        ‏2012-04-18T18:55:10Z  in response to SystemAdmin

                        Not quite. Yes DXL gives no error when there is no resolved body, but it does give an error when code HAS a reference to it; the error is at interpret time not execution time.

                        void A(string)    // unresolved
                        void B(string)    // unresolved
                        print "Hello\n"   // never executes
                        if (false) A("SS") // interpret error here
                        


                        Perhaps I'm missing something, but I see no particular problem if there is a forward declare that is not resolved and is also not used. That's like a function with an infinite loop that is never called, who cares? You would get the error if you did try to use it.

                        -Louie

                        Updated on 2014-01-06T20:19:48Z at 2014-01-06T20:19:48Z by iron-man
                        • SystemAdmin
                          SystemAdmin
                          3180 Posts
                          ACCEPTED ANSWER

                          Re: Function pointers

                          ‏2012-04-18T19:55:19Z  in response to llandale
                          re: "... who cares? You would get the error if you did try to use it."

                          It all depends what you are using an interface for. If it is your own stuff and you didn't implement a method nor call it, I agree. Who cares?

                          If you are using an interface as a contract to another developer (or even third party) to say "You shall write code to implement this interface". If the module is library-like with loads of methods, a single app is unlikely to use all the module's methods. But you may be counting on all the methods being at least implemented in case some other future app tries to use another method in the interface spec.

                          The point I'm trying to make is with many languages (e.g., C, Java) you will know right away if a method was not implemented. With DXL you would have to have some form of an acceptance test that (as a minimum) calls all methods in the interface that some developer was supposed to fulfill.

                          So Louie, I agree in some cases, the "... who cares?" is valid.

                          On the other hand, if an interface was part of a request to a developer like "Here is a statement of work and an .INC file with forward declarations I want you to implement."

                          The notion in this case is "I wouldn't have put a method in and interface spec if I didn't expect you to implement it."

                          So I agree with "Who cares?" for personal work but it may lead to an unforeseen last minute issues if you think you have all functionality stated in the interface spec, but in reality it has some holes in it.
                          • llandale
                            llandale
                            2943 Posts
                            ACCEPTED ANSWER

                            Re: Function pointers

                            ‏2012-04-18T21:59:21Z  in response to SystemAdmin

                            So in that one particular case which will come up a max twice in your lifetime, you must write an additional testing routine, turning your forward declare include into an actual call include.
                            If this is your forward declare contract:...

                            void a(string)
                            void b(void)
                            


                            ... Then you need to do this to overcome this "limitation" of DOORS

                             

                            #include forward declare contract
                            #include stuff from the coder
                            halt
                            a("")
                            b()
                            


                            Not trying to be abrasive, but if you think this is pretty serious you need to stop using DXL now because you are going to run into all sorts of annoying "features" that exist in other languages. Not to mention down right bugs:

                             

                             

                            string A(string s)
                            {  return "<<in 'A', s = [" s "]>>"
                            }
                            print "Line1 " (A("Hello")) " but now this\n"
                            print "Line2 "  A("Hello")  " but now this\n"
                            


                            Both print statements are functionally identical, but you get this:

                             

                             

                            Line1 <<in 'A', s = [Hello]>> but now this
                            Line2 <<in 'A', s = [Hello but now this
                            ]>>
                            


                            the 2nd one, notice that "but now this" is passed into A ignoring the end paren ")". Figuring out how that came about is harder than figuring out why hot dogs come in packs of 10 yet buns in packs of 8.

                            -Louie

                            Repeat after me: "Howuuuuuuuuuummmmm, it is what it is"

                             

                            Updated on 2014-01-06T20:21:32Z at 2014-01-06T20:21:32Z by iron-man
                            • SystemAdmin
                              SystemAdmin
                              3180 Posts
                              ACCEPTED ANSWER

                              Re: Function pointers

                              ‏2012-04-18T22:51:14Z  in response to llandale
                              In addition to peer help, one of the forums purposes is to share non-obvious behavioral observances.

                              I'm not complaining rather I'm documenting a behavior (a.k.a. "a feature") that may not be obvious especially to users that came from a C, C++, or Java world.

                              Why? If you know about DXL true behavior in advance you can take it into consideration in your designs.

                              There are plenty of downright bugs (as you have illustrated). I'd put this one in the not so well documented features category.
    • llandale
      llandale
      2943 Posts
      ACCEPTED ANSWER

      Re: Function pointers

      ‏2012-04-13T14:43:05Z  in response to SystemAdmin

      Nested functions are practically worthless in DXL since they may not access variables declared in the parent function. This makes them somewhat worthless.

      struct Toto {}
       
      int y = 5
      void titi(Toto toto, int b){
          int x = 1
       
              void fptr(Toto toto, int b) {
                      print ">>fptr; x = " x "\n"
                      print ">>fptr; b/y = " b "\t" y "\n"
              };
              fptr(toto, b)
      }
       
      void tutu(Toto toto, int b){
              titi(toto,b)
      }
       
      Toto tt = null
      tutu(tt, 6)
      


      You get "non local variable access (x) error. If you comment out the "print x" command, we see that the nested function can indeed access globabl variables.

      Updated on 2014-01-06T23:05:00Z at 2014-01-06T23:05:00Z by iron-man