Solved

Converting a function-like macro to a function

Posted on 2009-07-06
4
157 Views
Last Modified: 2012-05-07
I'm using the Flex/Bison combination and is adjusting it to my needs.
I'm nearly done, but something gets wrong with my input-data, and I'm trying to trace the error.

Here I hit a roadblock, because the data is read by a function-like macro, and gdb seems to be unable to step into a macro.

How do I replace the macro with "real" code, so that it becomes easier to debug it?
Alternatively, can I make gdb step in this code?

The macro isn't huge, so I'm gonna try to work it out regardless, but I find the question interesting :)
// Original macro

#ifndef YY_INPUT

#define YY_INPUT(buf,result,max_size) \

   if ( YY_CURRENT_BUFFER_LVALUE->yy_is_interactive ) \

      { \

      int c = '*'; \

      int n; \

      for ( n = 0; n < max_size && \

              (c = getc( yyin )) != EOF && c != '\n'; ++n ) \

         buf[n] = (char) c; \

      if ( c == '\n' ) \

         buf[n++] = (char) c; \

      if ( c == EOF && ferror( yyin ) ) \

         YY_FATAL_ERROR( "input in flex scanner failed" ); \

      result = n; \

      } \

   else \

      { \

      errno=0; \

      while ( (result = fread(buf, 1, max_size, yyin))==0 && ferror(yyin)) \

         { \

         if( errno != EINTR) \

            { \

            YY_FATAL_ERROR( "input in flex scanner failed" ); \

            break; \

            } \

         errno=0; \

         clearerr(yyin); \

         } \

      }\

\
 

#endif
 

//My replacement below

#undef YY_INPUT

#define YY_INPUT(buf,result,max_size) { \

   if(done == 1) (yy_n_chars) = YY_NULL;\

   else {\

      std::ostringstream str;\

      int j = 0;\

      do {\

         str << progs[progPointer] << " ";\

      } while (progs[progPointer++] != 99.0f && str.str().size() < num_to_read);\

\

      for(;j < str.str().size(); j++)\

         (&(yy_buffer_stack)[(yy_buffer_stack_top)]->yy_ch_buf[number_to_move])[j] = str.str().c_str()[j];\

\

      (yy_n_chars) = j;\

      if(progs[i] == 99.0f)\

      done = 1;\

   }\

}\
 

//Calling code

      YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]),

         (yy_n_chars), (size_t) num_to_read );

Open in new window

0
Comment
Question by:letharion
  • 3
4 Comments
 
LVL 53

Expert Comment

by:Infinity08
ID: 24783443
>> Here I hit a roadblock, because the data is read by a function-like macro, and gdb seems to be unable to step into a macro.

A macro is not a function - whenever you "call" a macro, it is replaced inline with the code for the macro, so there's no function call that gdb can step into.


>> How do I replace the macro with "real" code, so that it becomes easier to debug it?

Make it a function call :
void fun(/* the arguments ... */) {

  // whatever you want to do ...

}
 

#define MACRO(/* the arguments ... */) fun(/* the arguments ... */)

Open in new window

0
 
LVL 53

Accepted Solution

by:
Infinity08 earned 250 total points
ID: 24783470
So, for your example, you'd get something like (verify that it's correct, because your macro code was very strange, as it didn't use the arguments ...) :
void my_yy_input(int *buf, int &yy_n_chars, size_t num_to_read) {

  if (done == 1) {

    yy_n_chars = YY_NULL;

  }

  else {

    std::ostringstream str;

    int j = 0;

    do {

      str << progs[progPointer] << " ";

    } while (progs[progPointer++] != 99.0f && str.str().size() < num_to_read);
 

    for (; j < str.str().size(); j++) {

      buf[j] = str.str().c_str()[j];

    }
 

    yy_n_chars = j;

    if (progs[i] == 99.0f) {

      done = 1;

    }

  }

}
 

#define YY_INPUT(buf, result, max_size) my_yy_input(buf, result, max_size)

Open in new window

0
 
LVL 6

Author Comment

by:letharion
ID: 24783658
Thank you, works well :)

>your macro code was very strange, as it didn't use the arguments
Thanks for pointing that out. After experimenting with directly replacing the macro with code and going back, I had accidentally left the names of the variables like they are before in the scope outside of the function.

>A macro is not a function - whenever you "call" a macro, it is replaced inline with the code for the macro, so there's no function call that gdb can step into.
I thought this was done by the PP before compilation, and thus gdb could (in theory) have done the same. But maybe I've missunderstood the process, or gdb just has not implemented that function. (Maybe it'd be harder than I imagine)
In both mine, and therefore your code, progs[i] is used, and now that I have a function I get the expected complaint that i is undefined. This "just worked" in the macro, which wasn't to my advantage.
0
 
LVL 53

Expert Comment

by:Infinity08
ID: 24783736
>> I thought this was done by the PP before compilation

Exactly. The pre-processor modifies the source code before passing it to the compiler. So, the compiler is never aware that there even was a macro to begin with. The generated code that gdb works with has no function call as a result.
0

Featured Post

Threat Intelligence Starter Resources

Integrating threat intelligence can be challenging, and not all companies are ready. These resources can help you build awareness and prepare for defense.

Join & Write a Comment

Suggested Solutions

Title # Comments Views Activity
Problem to save 10 122
Socket Programming (Unix) 8 102
Global Keyboard Hooks Blocked 4 58
Raspberry Pi 3 to send text message 7 16
This tutorial is posted by Aaron Wojnowski, administrator at SDKExpert.net.  To view more iPhone tutorials, visit www.sdkexpert.net. This is a very simple tutorial on finding the user's current location easily. In this tutorial, you will learn ho…
This is a short and sweet, but (hopefully) to the point article. There seems to be some fundamental misunderstanding about the function prototype for the "main" function in C and C++, more specifically what type this function should return. I see so…
Video by: Grant
The goal of this video is to provide viewers with basic examples to understand and use for-loops in the C programming language.
Video by: Grant
The goal of this video is to provide viewers with basic examples to understand and use nested-loops in the C programming language.

760 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

22 Experts available now in Live!

Get 1:1 Help Now