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.
Related
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).
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++.
So imagine I had the code:
#define ID_BUTTON 1
in order to give myself a variable to use when using the CreateWindow() function to create a button.
Now, is it possible for me to use a method to return ID_BUTTON? Usually I'd find it relatively easy, but I don't know what function type I'd have to specify.
So,
1) Is it possible?
2) If so, what function type would I have to use?
Remember it'll just be simple code like:
<function_type> getID() {
return ID_BUTTON;
}
Thanks,
Jay
Technically speaking, what you want is actually possible using C++11 decltype:
#define ID_BUTTON 1
auto getID() -> decltype(ID_BUTTON)
{
return ID_BUTTON;
}
int main()
{
auto x = getID();
}
There, no need to specify int anywhere for ID_BUTTON or the function.
The real answer to your question, however, should be: Don't use macros for constants. C++ has const (and, as of recently) constexpr for that.
Assuming you don't understand what
#define ID_BUTTON 1
even does:
The #define, const, constexpr, and enum statements don't create variables; they create cconstants. Both variables and constants are identifiers that refer to values in your program. The difference is that constants cannot be changed at runtime, while variables can.
#define doesn't create just any ordinary constant, however. It actually tells a part of the compiler called the preprocessor to actually replace the text ID_BUTTON in your source code with the string 1. This can be useful, and this is what you have to do for C, but in C++, a constexpr (which was introduced in C++11) is usually more optimal. See Christian Hackl's answer for more on that.
If you're going to use a constant to pass values to an API, which is what you're planning on doing with ID_BUTTON, the API will usually tell you what type it expects, so you can use that type instead of having the compiler determine the best type for the job. However, see my discussion below on control identifiers in Windows, as there's a catch for the specific case of ID_BUTTON.
If you're in control of the type, you'll have to use a little more thought to figure out what type to use. In some cases, the language's type promotion rules will let you get away with just saying 1 without a type, but if you're creating known small or large integers, or bit fields, or floating-point numbers, you'll need to use the appropriate type name or qualifiers (short, long, unsigned, float, double, etc.). It takes a little time to figure out where to go, but once you've done it enough you'll be natural at it.
Assuming you don't understand how control identifiers in Windows works:
Most of the API functions that take a control identifier, such as GetDlgItem(), take the control identifier as an int; your control identifiers should thus have type int.
However, CreateWindow() and CreateWindowEx() expect the control identifier as the third to last parameter. This parameter is of type HMENU. C++ won't let you shove an int into an HMENU, so you'll have to use a cast: (HMENU) ID_BUTTON. (There's probably an equivalent C++-style cast, but I don't know/forget what it is.)
In addition, if you're going to use a resource file, you'll have to use #define statements to create your ID_xxx constant names, as the resource file format doesn't have const, constexpr, or enum. In this case, continue using #define for the identifiers, shove these #defines in their own include file, and #include that file from both your C++ source and the resource file.
If you're not using a resource file, you don't need to worry about using control identifiers at all; just use the HWND for each control directly. You should still assign control identifiers in case you need tab navigation or other dialog box message processing in your windows, but other than that you can just use the HWNDs directly. (I forget if control identifiers are involved in tab navigation or not.)
Finally, there are a number of predefined control identifiers that have special meaning to the dialog manager. This is from Microsoft's winuser.h:
/*
* Dialog Box Command IDs
*/
#define IDOK 1
#define IDCANCEL 2
#define IDABORT 3
#define IDRETRY 4
#define IDIGNORE 5
#define IDYES 6
#define IDNO 7
#if(WINVER >= 0x0400)
#define IDCLOSE 8
#define IDHELP 9
#endif /* WINVER >= 0x0400 */
Your own control identifiers should avoid colliding with these; your ID_BUTTON conflicts with IDOK. (If they do collide, you'll see weird things like your controls activating on keyboard shortcuts that the dialog manager knows about, for example.) The canonical solution to this problem is to start numbering your control identifiers at 100 (I believe Visual Studio was responsible for this, but I don't know for sure).
Hello all I was having trouble with macros so I thought I would practice and I was looking at the ## macro operator and thought I could use it for my problem I wan't to be able to call multiple functions based on the parameter for example if I have a macro like so:
#define macro(a) func##a();
int main()
{
.....
for(int i = 0;i< length;i++)
{
macro(i)
}
func1()
{
}
....
func31()
{
}
Anyone have an idea of how I can accomplish this??
You can only combine two preprocessor tokens. However, func isn't a preprocessor token. You need to jump through an extra hoop, calling some form of "concat" macro:
#define CONCAT(a, b) a ## b
#define macro(a) CONCAT(func,a)
Of course, the tokens produced by you macro won't be func1, ..., func31 (of course, they would also need to start with func0 if your logic were correct) but rather funci. The expansion of macros happens at the beginning of compilation while the execution of the for-loop happens at run-time (some optimizations may hoist it into compile-time but that won't affect the macros).
If you need to expand a sequence of integers in combination with a macro, you may want to have a look at the Boost preprocessor library, in particular at the BOOST_PP_REPEAT functionality.
If you just need to statically expand a sequence of integers to function calls, you might also consider looking at function template templatized on an integers: I would certainly consider using an approach using templates before trying to use the preprocessor library...
What is the point of #define in C++? I've only seen examples where it's used in place of a "magic number" but I don't see the point in just giving that value to a variable instead.
The #define is part of the preprocessor language for C and C++. When they're used in code, the compiler just replaces the #define statement with what ever you want. For example, if you're sick of writing for (int i=0; i<=10; i++) all the time, you can do the following:
#define fori10 for (int i=0; i<=10; i++)
// some code...
fori10 {
// do stuff to i
}
If you want something more generic, you can create preprocessor macros:
#define fori(x) for (int i=0; i<=x; i++)
// the x will be replaced by what ever is put into the parenthesis, such as
// 20 here
fori(20) {
// do more stuff to i
}
It's also very useful for conditional compilation (the other major use for #define) if you only want certain code used in some particular build:
// compile the following if debugging is turned on and defined
#ifdef DEBUG
// some code
#endif
Most compilers will allow you to define a macro from the command line (e.g. g++ -DDEBUG something.cpp), but you can also just put a define in your code like so:
#define DEBUG
Some resources:
Wikipedia article
C++ specific site
Documentation on GCC's preprocessor
Microsoft reference
C specific site (I don't think it's different from the C++ version though)
Mostly stylistic these days. When C was young, there was no such thing as a const variable. So if you used a variable instead of a #define, you had no guarantee that somebody somewhere wouldn't change the value of it, causing havoc throughout your program.
In the old days, FORTRAN passed even constants to subroutines by reference, and it was possible (and headache inducing) to change the value of a constant like '2' to be something different. One time, this happened in a program I was working on, and the only hint we had that something was wrong was we'd get an ABEND (abnormal end) when the program hit the STOP 999 that was supposed to end it normally.
I got in trouble at work one time. I was accused of using "magic numbers" in array declarations.
Like this:
int Marylyn[256], Ann[1024];
The company policy was to avoid these magic numbers because, it was explained to me, that these numbers were not portable; that they impeded easy maintenance. I argued that when I am reading the code, I want to know exactly how big the array is. I lost the argument and so, on a Friday afternoon I replaced the offending "magic numbers" with #defines, like this:
#define TWO_FIFTY_SIX 256
#define TEN_TWENTY_FOUR 1024
int Marylyn[TWO_FIFTY_SIX], Ann[TEN_TWENTY_FOUR];
On the following Monday afternoon I was called in and accused of having passive defiant tendencies.
#define can accomplish some jobs that normal C++ cannot, like guarding headers and other tasks. However, it definitely should not be used as a magic number- a static const should be used instead.
C didn't use to have consts, so #defines were the only way of providing constant values. Both C and C++ do have them now, so there is no point in using them, except when they are going to be tested with #ifdef/ifndef.
Most common use (other than to declare constants) is an include guard.
Define is evaluated before compilation by the pre-processor, while variables are referenced at run-time. This means you control how your application is built (not how it runs)
Here are a couple examples that use define which cannot be replaced by a variable:
#define min(i, j) (((i) < (j)) ? (i) : (j))
note this is evaluated by the pre-processor, not during runtime
http://msdn.microsoft.com/en-us/library/8fskxacy.aspx
The #define allows you to establish a value in a header that would otherwise compile to size-greater-than-zero. Your headers should not compile to size-greater-than-zero.
// File: MyFile.h
// This header will compile to size-zero.
#define TAX_RATE 0.625
// NO: static const double TAX_RATE = 0.625;
// NO: extern const double TAX_RATE; // WHAT IS THE VALUE?
EDIT: As Neil points out in the comment to this post, the explicit definition-with-value in the header would work for C++, but not C.