Want to win a PS4? Go Premium and enter to win our High-Tech Treats giveaway. Enter to Win

x
?
Solved

Converting a function-like macro to a function

Posted on 2009-07-06
4
Medium Priority
?
177 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
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 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 1000 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

Concerto's Cloud Advisory Services

Want to avoid the missteps to gaining all the benefits of the cloud? Learn more about the different assessment options from our Cloud Advisory team.

Question has a verified solution.

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

Preface I don't like visual development tools that are supposed to write a program for me. Even if it is Xcode and I can use Interface Builder. Yes, it is a perfect tool and has helped me a lot, mainly, in the beginning, when my programs were small…
Examines three attack vectors, specifically, the different types of malware used in malicious attacks, web application attacks, and finally, network based attacks.  Concludes by examining the means of securing and protecting critical systems and inf…
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.
The goal of this video is to provide viewers with basic examples to understand opening and reading files in the C programming language.

610 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