Function call sequence

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • mjm

    Function call sequence

    Folks,

    I have the following problem: when using arrays or matrices I often
    write past the index bounds. To prevent this from happening I check
    the bounds and return an error message such as

    Matrix: index i=... not in [....]

    However this is only of limited help since all I know now is that the
    subscripting operator of Matrix was applied incorrectly.

    What I really would like to know is what function called this
    subscripting operator so I can tell where the mistake happened.

    Is there a good solution to this?
  • Karl Heinz Buchegger

    #2
    Re: Function call sequence



    mjm wrote:[color=blue]
    >
    > Folks,
    >
    > I have the following problem: when using arrays or matrices I often
    > write past the index bounds. To prevent this from happening I check
    > the bounds and return an error message such as
    >
    > Matrix: index i=... not in [....]
    >
    > However this is only of limited help since all I know now is that the
    > subscripting operator of Matrix was applied incorrectly.
    >
    > What I really would like to know is what function called this
    > subscripting operator so I can tell where the mistake happened.
    >
    > Is there a good solution to this?[/color]

    No.
    The best thing is dependent on your development system.
    Figure out how to stop program execution and switch to
    a debugger. The debugger then can be used to walk back the call
    stack.

    --
    Karl Heinz Buchegger
    kbuchegg@gascad .at

    Comment

    • Karl Heinz Buchegger

      #3
      Re: Function call sequence



      Karl Heinz Buchegger wrote:[color=blue]
      >
      > mjm wrote:[color=green]
      > >
      > > Folks,
      > >
      > > I have the following problem: when using arrays or matrices I often
      > > write past the index bounds. To prevent this from happening I check
      > > the bounds and return an error message such as
      > >
      > > Matrix: index i=... not in [....]
      > >
      > > However this is only of limited help since all I know now is that the
      > > subscripting operator of Matrix was applied incorrectly.
      > >
      > > What I really would like to know is what function called this
      > > subscripting operator so I can tell where the mistake happened.
      > >
      > > Is there a good solution to this?[/color]
      >
      > No.
      > The best thing is dependent on your development system.
      > Figure out how to stop program execution and switch to
      > a debugger. The debugger then can be used to walk back the call
      > stack.[/color]

      Actually there is a way, which involves use of the preprocessor.

      Assuming that your access to the matrix is enclosed in a function.

      int GetValue( int x, int y );

      you can add additional arguments to this function:

      int GetValue( int x, int y, const char* File, const char* Line )
      {
      if( x_or_y_are_out_ of_bounds ) {
      cout << "out of bounds, called from " << File << " Line: " << Line << endl;
      ...
      }
      }

      Normally you would use this function as in

      z = GetValue( 3, 4, __FILE__, __LINE__ );

      But since this gets boring, you use the preprocessor
      to create a macro which brings in the last 2 arguments.

      #define GetValue(a,b) GetValue(a,b,__ FILE__,__LINE__ )

      z = GetValue(3, 4);

      This also has the advantage that you can create different versions
      for the debug and release builds easily.

      --
      Karl Heinz Buchegger
      kbuchegg@gascad .at

      Comment

      • Agent Mulder

        #4
        Re: Function call sequence

        MJM>all I know now is that the subscripting operator of
        MJM>Matrix was applied incorrectly.

        How does the subscripting operator of Matrix looks like? Or,
        if that is easier, the whole of class Matrix? I need some context
        to think about your question..

        -X



        Comment

        • Sven Gohlke

          #5
          Re: Function call sequence

          Karl Heinz Buchegger wrote:
          [color=blue]
          > Actually there is a way, which involves use of the preprocessor.
          >
          > Assuming that your access to the matrix is enclosed in a function.
          >
          > int GetValue( int x, int y );
          >
          > you can add additional arguments to this function:
          >
          > int GetValue( int x, int y, const char* File, const char* Line )
          > {
          > if( x_or_y_are_out_ of_bounds ) {
          > cout << "out of bounds, called from " << File << " Line: " << Line <<
          > endl; ...
          > }
          > }
          >
          > Normally you would use this function as in
          >
          > z = GetValue( 3, 4, __FILE__, __LINE__ );
          >
          > But since this gets boring, you use the preprocessor
          > to create a macro which brings in the last 2 arguments.
          >
          > #define GetValue(a,b) GetValue(a,b,__ FILE__,__LINE__ )
          >
          > z = GetValue(3, 4);
          >
          > This also has the advantage that you can create different versions
          > for the debug and release builds easily.[/color]

          Since __FILE__ and __LINE__ maybe provided by the preprocessor You should
          use __func__ instead which is guaranteed to be a local variable (according
          to C99).
          --
          Best Regards
          Sven

          Comment

          • Karl Heinz Buchegger

            #6
            Re: Function call sequence



            Sven Gohlke wrote:[color=blue]
            >
            >
            > Since __FILE__ and __LINE__ maybe provided by the preprocessor You should
            > use __func__ instead which is guaranteed to be a local variable (according
            > to C99).[/color]

            as you say: C99
            but this is comp.lang.c++

            --
            Karl Heinz Buchegger
            kbuchegg@gascad .at

            Comment

            • mjm

              #7
              Re: Function call sequence

              You can download the whole class from

              by following the link to CVS
              (don't go to download -- that's Java code).

              The subscript checking is in Array.h.

              I don't think the context is necessary though.
              The problem is to identify from within a call to a C++ function g(...)
              the function which made the call to g(...).

              I don't understand the solutions offered so far.
              The function g could look like

              void g(const RealArray1D& x)
              {
              for(int i=0;i<n;i++) {/*do something with x[i]*/}
              }

              The perpetrator i is local and does not show up in the
              signature of g. I guess stopping execution and using the debugger
              is the only solution.

              For example in Java you get the call sequence
              when an exception is thrown.

              Comment

              • mjm

                #8
                Re: Function call sequence

                Karl Heinz Buchegger <kbuchegg@gasca d.at> wrote in message news:<3F16949C. 92AC1675@gascad .at>...[color=blue]
                > Sven Gohlke wrote:[color=green]
                > >
                > >
                > > Since __FILE__ and __LINE__ maybe provided by the preprocessor You should
                > > use __func__ instead which is guaranteed to be a local variable (according
                > > to C99).[/color]
                >
                > as you say: C99
                > but this is comp.lang.c++[/color]

                OK, I believe I get it now.
                The const char* go into the subscripting operator which is then always
                called as

                X(i,j,__FILE__, __LINE__)

                I learned something.
                What happens when the strings are passed.
                If the whole string is copied this could slow down things by several
                orders of magnitude since subscripting typically happens in the
                innermost loops.

                Anyway I like it.

                Many thanks.

                Comment

                • Karl Heinz Buchegger

                  #9
                  Re: Function call sequence



                  mjm wrote:[color=blue]
                  >
                  > Karl Heinz Buchegger <kbuchegg@gasca d.at> wrote in message news:<3F16949C. 92AC1675@gascad .at>...[color=green]
                  > > Sven Gohlke wrote:[color=darkred]
                  > > >
                  > > >
                  > > > Since __FILE__ and __LINE__ maybe provided by the preprocessor You should
                  > > > use __func__ instead which is guaranteed to be a local variable (according
                  > > > to C99).[/color]
                  > >
                  > > as you say: C99
                  > > but this is comp.lang.c++[/color]
                  >
                  > OK, I believe I get it now.
                  > The const char* go into the subscripting operator which is then always
                  > called as
                  >
                  > X(i,j,__FILE__, __LINE__)[/color]

                  yep. The additional macro just hides this. So the programmer
                  doesn't need to remember to add those 2 arguments.
                  [color=blue]
                  >
                  > I learned something.
                  > What happens when the strings are passed.
                  > If the whole string is copied this could slow down things by several
                  > orders of magnitude since subscripting typically happens in the
                  > innermost loops.[/color]

                  Look again at the function signature. There are no strings
                  involved, only character pointers.
                  [color=blue]
                  >
                  > Anyway I like it.[/color]

                  It's a littel bit of help. But breaking to the debugger is
                  usually better. The reason is that knowing where this specific
                  call came from often isn't very usefully. The calling function
                  was called from somewhere else, which was called elsewhere, etc.
                  So a complete call stack is needed often but not provided with this
                  technique.

                  --
                  Karl Heinz Buchegger
                  kbuchegg@gascad .at

                  Comment

                  Working...