Solved

Converting a function-like macro to a function

Posted on 2009-07-06
4
159 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

Microsoft Certification Exam 74-409

Veeam® is happy to provide the Microsoft community with a study guide prepared by MVP and MCT, Orin Thomas. This guide will take you through each of the exam objectives, helping you to prepare for and pass the examination.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Title # Comments Views Activity
Microsoft vcsetup.exe and vcssetup.exe 8 413
how to declare a 2-dimensional version of strlen 4 202
Adjust Mfcapp 29 160
Grammars for C C++ and java 1 114
Have you thought about creating an iPhone application (app), but didn't even know where to get started? Here's how: ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ Important pre-programming comments: I’ve never tri…
Summary: This tutorial covers some basics of pointer, pointer arithmetic and function pointer. What is a pointer: A pointer is a variable which holds an address. This address might be address of another variable/address of devices/address of fu…
The goal of this video is to provide viewers with basic examples to understand recursion in the C programming language.
Video by: Grant
The goal of this video is to provide viewers with basic examples to understand and use while-loops in the C programming language.

863 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

26 Experts available now in Live!

Get 1:1 Help Now