What is the Action of #define in this Instance? - c++

As part of my homework, I've been given this code to help with the task they've given us... to create a basic shell that supports piping, background processes, and a number of builtin commands, etc. I've read through the code they've given us for parsing...
I'm familiar with the #define keyword in C, however, I've not seen it used like in the below code: namely, what is c for? I'm guessing it has been assigned to mean a character but I'm not sure:
#define PIPE ('|')
#define BG ('&')
#define RIN ('<')
#define RUT ('>')
#define ispipe(c) ((c) == PIPE)
#define isbg(c) ((c) == BG)
#define isrin(c) ((c) == RIN)
#define isrut(c) ((c) == RUT)
#define isspec(c) (ispipe(c) || isbg(c) || isrin(c) || isrut(c))
Any help or advice much appreciated.

The last five #define statements you give define macros, each taking an argument, which is here always called c. Your first four #define statements are also, technically, macros, but they don't need an argument - they are simply substituted for their 'values' when encountered; frequently, programmers refer to macros with no argument as tokens, with the PIPE token here having a token value of ('|').
Later on in the file (possibly) there will be cases where one or more of these macros is called, and that call will have a value for the actual argument, like this, for example:
if (ispipe(test_arg)) ++npipes;
This macro "call" will be replaced (by the pre-processor) with the following expansion:
if (((test) == ('|')) ++npipes;
And, similarly, for the other #define XXX(c) macros.
Note: It is quite common to add (lots of) parentheses in macro definitions, just to be sure that the code does what you 'think' it will after the pre-processor has done its stuff.
Feel free to ask for further explanation and/or clarification.

#define is not a function, it is a preprocessor directive.
c could be anything. If you write ispipe(42), then the preprocessor will change it into ((42) == PIPE). If you write ispipe(while(1);), then the preprocessor will change it into ((while(1);) == PIPE), which will dumbfound the compiler when it reads it.
The preprocessor is blind, and does not know much about C syntax, and nothing of its semantics; the only way to understand what c is supposed to be is either to reverse-engineer the intended usage, or to ask whoever wrote the code without comments to tell you what they meant.
After the edit, it is rather reasonable to expect that c should be a char, in order to be meaningfully compared to '|' and similar. But even passing 0xDEADBEEF should compile correctly (returning FALSE).

Related

Using MACROs to get the 'name' of function parameters

I've implemented a log function, that eventually is being used identically all over the code.
void func(int foo, int bar){
log_api_call("foo", foo, "bar",bar)
...
}
so I've decided to make it easier and just extract the variable names.
so it would be something like
log_api_call(foo,bar)
or even better
log_api_call()
and it would expand to log_api_call("foo", foo, "bar",bar) somehow.
I have no idea even where to start to 'extract' the function variable names.
help would be much appreciated.
Edit:
I understand that what I've asked previously is outside of the C++ preprocessor capabilities, but can C MACROS expand log_api(a,b) to log_api_call("a", a, "b", b) for any number of parameters?
for defined number the job is trivial.
Thanks.
This isn't actually too difficult.
I'd recommend a slight change in spec though; instead of:
expand log_api(a,b) to log_api_call("a", a, "b", b)
...it's more useful to expand something like NAMED_VALUES(a,b) to "a",a,"b",b. You can then call log_api(NAMED_VALUES(a,b)), but your log_api can stay more generic (e.g., log_api(NAMED_VALUES(a,b),"entering function") is possible). This approach also avoids a lot of complications about zero-argument cases.
// A preprocessor argument counter
#define COUNT(...) COUNT_I(__VA_ARGS__, 9, 8, 7, 6, 5, 4, 3, 2, 1,)
#define COUNT_I(_9,_8,_7,_6,_5,_4,_3,_2,_1,X,...) X
// Preprocessor paster
#define GLUE(A,B) GLUE_I(A,B)
#define GLUE_I(A,B) A##B
// chained caller
#define NAMED_VALUES(...) GLUE(NAMED_VALUES_,COUNT(__VA_ARGS__))(__VA_ARGS__)
// chain
#define NAMED_VALUES_1(a) #a,a
#define NAMED_VALUES_2(a,...) #a,a,NAMED_VALUES_1(__VA_ARGS__)
#define NAMED_VALUES_3(a,...) #a,a,NAMED_VALUES_2(__VA_ARGS__)
#define NAMED_VALUES_4(a,...) #a,a,NAMED_VALUES_3(__VA_ARGS__)
#define NAMED_VALUES_5(a,...) #a,a,NAMED_VALUES_4(__VA_ARGS__)
#define NAMED_VALUES_6(a,...) #a,a,NAMED_VALUES_5(__VA_ARGS__)
#define NAMED_VALUES_7(a,...) #a,a,NAMED_VALUES_6(__VA_ARGS__)
#define NAMED_VALUES_8(a,...) #a,a,NAMED_VALUES_7(__VA_ARGS__)
#define NAMED_VALUES_9(a,...) #a,a,NAMED_VALUES_8(__VA_ARGS__)
This supports up to 9 arguments, but it should be easy to see how to expand to more.
This is not possible in standard C++11 (or standard C11 - which nearly shares its preprocessor with C++). The C or C++ preprocessor don't know the AST of your code passed to the compiler (because it is running before the actual parsing of your code).
I have no idea even where to start to 'extract' the function variable names.
Notice that variable and function names are known only at compilation time (after preprocessing). So if you want them, you need to work during compilation. At execution time variables and functions names are generally lost (and you could strip your executable).
You could generate your C++ code (e.g.using some other preprocessor like GPP or M4, or writing your own thing).
You could customize your C++ compiler (e.g. with an extension in GCC MELT, or a GCC plugin) to e.g. have log_api_call invoke some new magic builtin (whose processing inside the compiler would do most of the job). This would take months and is very compiler specific, I don't think it is worth the pain.
You could parse DWARF debugging info (that would also take months, so I don't think it would be wise).
(I am implicitly thinking of C++ code compiled on a Linux system)
Read more about aspect programming.
If you want such powerful meta-programming facilities, C++ is the wrong programming language. Read more about the powerful macro system of Common Lisp...
but can C MACROS expand log_api(a,b) to log_api_call("a", a, "b", b) for any number of parameters? for defined number the job is trivial.
No. You need a more powerful preprocessor to do that job (or write your own). For that specific need, you might consider customizing your source code editor (e.g. write a hundred lines of ELisp code doing that extraction & expansion job at edit time for emacs).
PS In practice you could find some library (probably boost) limiting the arguments to some reasonable limit
I think the best you can achieve from inside the language is writing a macro LOG_API_CALL(foo,bar) that expands to log_api_call("foo", foo, "bar", bar):
#define LOG_API_CALL(P1,P2) log_api_call(#P1,P1,#P2,P1)
This gets pretty tricky if you want to support arbitrarily many arguments with a single macro name, but you could also have a separate macro for each number of arguments.
and it would expand to log_api_call("foo", foo, "bar",bar) somehow.
This is not possible in Standard C++.

C++ #define variable parameter function

I have a CPU sensitive application and want to minimize function calls. I want to write something like:
#ifdef condition
#define f(a,b) ff(a,b)
#define f(a) ff(a)
#endif
But the compiler sees f as defined multiple times. I wanted to use __VAR_ARGS__ but in the example above b is of enum type. Is there a proper way to do it or I should just rename f(a,b) to f2(a,b)?
To clarify the defines, if active, add calls to functions that process data for printing to file/stdout, otherwise they are replaced with empty lines, so in my opinion this method would improve code size and since the macro is single line keyword like INFO(object->contents) I think it's more readable. Also it would have been useful if I could have added something like WARN("message") and WARN("value is",obj->printvalue()).
I also think inline would do the trick (from the answer below).
This is a very C-ish way of approaching this. Simply make it an overloaded inline function. Any optimiser worthy of the name will inline the call.
My first guess is that you are optimizing in the wrong areas. Good compilers will optimize in this case. Obfuscating code will make it harder for the compiler to do so.
Found the answer from the c++ book:
Macro names cannot be overloaded:
#define PRINT(a ,b ) cout <<(a )<<(b )
#define PRINT (a ,b ,c ) cout <<(a )<<(b )<<(c ) /* trouble?: redefines, does not overload */

How to make a Macro parser in C++ project

in the project, there are a lot of macros
such as
#define a (b+c)
#define b (e+d)
sometimes you need to decide the actual value of a .
so i am wondering if there are any tools for doing that, calculating all the macros and give the actual value as comment: (like below)
#define a (b+c) //a = 5
Are there any opensource project related on this macro parsing job?
thanx
I don't know how such a tool could exist as a macro may have an argument that is only known during execution(for instance #define sum(a,b) (a+b)). As for the value during runtime - any reasonable debugger will handle that.

C++ preprocessor directive

I have a macro which defines the model number of an equipment. I am having problems determining how to compare it to a string.
In a customer's specific header I have defined my macro as follows:
#define FTP_MODEL_NUM CT1030
Here I want to conditionally compile a section of code depending on the model number but no matter what value my macro has it compiles it anyway:
#if FTP_MODEL_NUM == CT1031
QMessageBox * lolers=new QMessageBox;
lolers->setWindowTitle(tr("title"));
lolers->setText(tr("this is test"));
lolers->show();
#endif
What am I missing? Do I absolutely need to compare it to another macro when using the == operator? I'm using Qt on Linux.
Assuming C++'s preprocessor works the same way as C99's, what you're trying to do can't work. After FTP_MODEL_NUM == CT1031 is expanded to, e.g., CT1030 == CT1031, any identifiers remaining in the expression are replaced with 0, yielding 0 == 0, which is always true. I believe the standard way to do what you're trying to do is to define a macro with the same name as the model number (e.g., #define CT1030) and then implement the test with #ifdef CT1031.
You cant lexically compare macros afaik. Only numerically. Define a second macro with numbers and use that.

Is there a C pre-processor which eliminates #ifdef blocks based on values defined/undefined?

Original Question
What I'd like is not a standard C pre-processor, but a variation on it which would accept from somewhere - probably the command line via -DNAME1 and -UNAME2 options - a specification of which macros are defined, and would then eliminate dead code.
It may be easier to understand what I'm after with some examples:
#ifdef NAME1
#define ALBUQUERQUE "ambidextrous"
#else
#define PHANTASMAGORIA "ghostly"
#endif
If the command were run with '-DNAME1', the output would be:
#define ALBUQUERQUE "ambidextrous"
If the command were run with '-UNAME1', the output would be:
#define PHANTASMAGORIA "ghostly"
If the command were run with neither option, the output would be the same as the input.
This is a simple case - I'd be hoping that the code could handle more complex cases too.
To illustrate with a real-world but still simple example:
#ifdef USE_VOID
#ifdef PLATFORM1
#define VOID void
#else
#undef VOID
typedef void VOID;
#endif /* PLATFORM1 */
typedef void * VOIDPTR;
#else
typedef mint VOID;
typedef char * VOIDPTR;
#endif /* USE_VOID */
I'd like to run the command with -DUSE_VOID -UPLATFORM1 and get the output:
#undef VOID
typedef void VOID;
typedef void * VOIDPTR;
Another example:
#ifndef DOUBLEPAD
#if (defined NT) || (defined OLDUNIX)
#define DOUBLEPAD 8
#else
#define DOUBLEPAD 0
#endif /* NT */
#endif /* !DOUBLEPAD */
Ideally, I'd like to run with -UOLDUNIX and get the output:
#ifndef DOUBLEPAD
#if (defined NT)
#define DOUBLEPAD 8
#else
#define DOUBLEPAD 0
#endif /* NT */
#endif /* !DOUBLEPAD */
This may be pushing my luck!
Motivation: large, ancient code base with lots of conditional code. Many of the conditions no longer apply - the OLDUNIX platform, for example, is no longer made and no longer supported, so there is no need to have references to it in the code. Other conditions are always true. For example, features are added with conditional compilation so that a single version of the code can be used for both older versions of the software where the feature is not available and newer versions where it is available (more or less). Eventually, the old versions without the feature are no longer supported - everything uses the feature - so the condition on whether the feature is present or not should be removed, and the 'when feature is absent' code should be removed too. I'd like to have a tool to do the job automatically because it will be faster and more reliable than doing it manually (which is rather critical when the code base includes 21,500 source files).
(A really clever version of the tool might read #include'd files to determine whether the control macros - those specified by -D or -U on the command line - are defined in those files. I'm not sure whether that's truly helpful except as a backup diagnostic. Whatever else it does, though, the pseudo-pre-processor must not expand macros or include files verbatim. The output must be source similar to, but usually simpler than, the input code.)
Status Report (one year later)
After a year of use, I am very happy with 'sunifdef' recommended by the selected answer. It hasn't made a mistake yet, and I don't expect it to. The only quibble I have with it is stylistic. Given an input such as:
#if (defined(A) && defined(B)) || defined(C) || (defined(D) && defined(E))
and run with '-UC' (C is never defined), the output is:
#if defined(A) && defined(B) || defined(D) && defined(E)
This is technically correct because '&&' binds tighter than '||', but it is an open invitation to confusion. I would much prefer it to include parentheses around the sets of '&&' conditions, as in the original:
#if (defined(A) && defined(B)) || (defined(D) && defined(E))
However, given the obscurity of some of the code I have to work with, for that to be the biggest nit-pick is a strong compliment; it is valuable tool to me.
The New Kid on the Block
Having checked the URL for inclusion in the information above, I see that (as predicted) there is an new program called Coan that is the successor to 'sunifdef'. It is available on SourceForge and has been since January 2010. I'll be checking it out...further reports later this year, or maybe next year, or sometime, or never.
I know absolutely nothing about C, but it sounds like you are looking for something like unifdef. Note that it hasn't been updated since 2000, but there is a successor called "Son of unifdef" (sunifdef).
Also you can try this tool http://coan2.sourceforge.net/
something like this will remove ifdef blocks:
coan source -UYOUR_FLAG --filter c,h --recurse YourSourceTree
I used unifdef years ago for just the sort of problem you describe, and it worked fine. Even if it hasn't been updated since 2000, the syntax of preprocessor ifdefs hasn't changed materially since then, so I expect it will still do what you want. I suppose there might be some compile problems, although the packages appear recent.
I've never used sunifdef, so I can't comment on it directly.
Around 2004 I wrote a tool that did exactly what you are looking for. I never got around to distributing the tool, but the code can be found here:
http://casey.dnsalias.org/exifdef-0.2.zip (that's a dsl link)
It's about 1.7k lines and implements enough of the C grammar to parse preprocessor statements, comments, and strings using bison and flex.
If you need something similar to a preprocessor, the flexible solution is Wave (from boost). It's a library designed to build C-preprocessor-like tools (including such things as C++03 and C++0x preprocessors). As it's a library, you can hook into its input and output code.