Shouldn't I be getting warning or error message after declaring macro in this way:
#define c 123
#define a b
#define b c
The code worked flawlessly - so just like variable definition, is macro definition stored somewhere?
This is perfectly fine, because preprocessor does not act upon macro definitions until the point of expansion. That is why the order does not matter: as long as each macro has a definition to which it could be expanded when your code makes a reference to it, the preprocessor is happy. This applies to macros that rely on other macros for their expansion.
One consequence of this behavior is that the relative order of macro declarations does not change the end result.
Related
I know about the argument prescan when an argument is used in a C macro, but that happens when you use an already defined macro. However, when you define it, do you need to have any special care at choosing the parameter names? Does the preprocessor parse the macro in an "atomic" way so that parameter names are not expanded?
I mean, imagine this scenario:
#define MYVAL {is this safe?}
#define ADDVALUES(MYVAL,YOURVAL) do{(MYVAL)+(YOURVAL);}while(0)
int val=ADDVALUES(1,3);
How is the ADDVALUES macro parsed? Is MYVAL expanded before defining the ADDVALUES macro?
I have not read any warning about choosing the parameter names in a macro, so I tend to believe their name is not expanded before the macro is parsed (I have read warnings about naming local variables in macros, about the macros names themselves, about swallowing the semicolon, etc., but nothing about choosing the parameter names).
The scope of the parameter MYVAL is distinct from that of the object-like macro MAYVAL. Quoting from the relevant part of the Standard, 6.10.3,p10:
The parameters are specified by the optional list of identifiers,
whose scope extends from their declaration in the identifier list
until the new-line character that terminates the #define preprocessing
directive.
The last line in the example given will be expanded as
int val=do{(1)+(3);}while(0);
I tried with gcc 4.8.5
#define NV1 a
#define V1(NV1) b NV1
V1(foo)
gcc -E test.h
Result
b foo
So parameter name is not expanded as a macro and overrides the earlier conflicting definition
I am trying to build a test that checks if a certain file defines a header guard with a certain namespace. Because the test is generic, this namespace is only known at compile-time and passed in as -DTHENAMESPACE=BLA. We then use some magic from https://stackoverflow.com/a/1489985/1711232 to paste that together.
This means I want to do something like:
#define PASTER(x, y) x##_##y
#define EVALUATOR(x, y) PASTER(x, y)
#define NAMESPACE(fun) EVALUATOR(THENAMESPACE, fun)
#ifndef NAMESPACE(API_H) // evaluates to BLA_API_H
# error "namespace not properly defined"
#endif
But this does not work properly, with cpp complaining about the ifndef not expecting the parentheses.
How can I do this properly, if it is possible at all?
I have also tried adding more layers of indirection, but not with a lot of success.
So directly, properly executing the #ifdef this at least appears to not be possible:
Considering the defined operator:
If the defined operator appears as a result of a macro expansion, the C standard says the behavior is undefined. GNU cpp treats it as a genuine defined operator and evaluates it normally. It will warn wherever your code uses this feature if you use the command-line option -Wpedantic, since other compilers may handle it differently. The warning is also enabled by -Wextra, and can also be enabled individually with -Wexpansion-to-defined.
https://gcc.gnu.org/onlinedocs/cpp/Defined.html#Defined
and ifdef expects a MACRO, and does not do further expansion.
https://gcc.gnu.org/onlinedocs/cpp/Ifdef.html#Ifdef
But maybe it is possible to trigger an 'undefined constant' warning (-Wundef), which would also allow my test pipeline to catch this problem.
If we assume that include guards always looks like
#define NAME /* no more tokens here */
and if, as you said, any compile time error (rather than #error exclusively) is acceptable, then you can do following:
#define THENAMESPACE BLA
#define BLA_API_H // Comment out to get a error.
#define CAT(x,y) CAT_(x,y)
#define CAT_(x,y) x##y
#define NAMESPACE(x) static int CAT(UNUSED_,__LINE__) = CAT(CAT(THENAMESPACE,CAT(_,x)),+1);
NAMESPACE(API_H)
Here, NAMESPACE(API_H) tries to concatenate BLA_API_H and + using ##.
This results in error: pasting "BLA_API_H" and "+" does not give a valid preprocessing token except if BLA_API_H is #defined to 'no tokens'.
In presence of #define BLA_API_H, NAMESPACE(API_H) simply becomes
static int UNUSED_/*line number here*/ = +1;
If you settle for a less robust solution, you can even get nice error messages:
#define THENAMESPACE BLA
#define BLA_API_H // Comment out to get a error.
#define TRUTHY_VALUE_X 1
#define CAT(x,y) CAT_(x,y)
#define CAT_(x,y) x##y
#define NAMESPACE(x) CAT(CAT(TRUTHY_VALUE_,CAT(THENAMESPACE,CAT(_,x))),X)
#if !NAMESPACE(API_H)
#error "namespace not properly defined"
#endif
Here, if BLA_API_H is defined, then #if !NAMESPACE(API_H) expands to #if 1.
If BLA_API_H is not defined, then it expands to #if TRUTHY_VALUE_BLA_API_HX, and TRUTHY_VALUE_BLA_API_HX evaluates to false due to being undefined.
The problem here is that if TRUTHY_VALUE_BLA_API_HX accidentally turns out to be defined to something truthy, you'll get a false negatie.
I don't think that macro expansion inside #ifndef directive is possible in the realm of standard C.
#ifndef symbol is equivalent of #if !defined symbol. Standard says this about it (§6.10.1 Conditional inclusion):
... it may contain unary operator expressions of the form
defined identifier
or
defined ( identifier )
and
Prior to evaluation, macro invocations in the list of preprocessing tokens that will become the controlling constant expression are replaced (except for those macro names modified by the defined unary
operator), just as in normal text. If the token defined is generated as a result of this replacement
process or use of the defined unary operator does not match one of the two specified forms prior to
macro replacement, the behavior is undefined. ...
So basically identifiers in defined expression are not expanded, and your current NAMESPACE(API_H) is not valid form of identifier.
Possible workaround could be to simply use:
#if NAMESPACE(API_H) == 0
# error "namespace not properly defined"
#endif
This works because non-existing identifiers are replaced with 0. Problem with this approach is that there will be false error if BLA_API_H is defined as 0, but depending on your situation that may be acceptable.
You can also do this using preprocessor pattern matching.
#define PASTE3(A,B,C) PASTE3_I(A,B,C)
#define PASTE3_I(A,B,C) A##B##C
#define PASTE(A,B) PASTE_I(A,B)
#define PASTE_I(A,B) A##B
#define THIRD(...) THIRD_I(__VA_ARGS__,,,)
#define THIRD_I(A,B,C,...) C
#define EMPTINESS_DETECTOR ,
#if THIRD(PASTE3(EMPTINESS_,PASTE(THENAMESPACE,_API_H),DETECTOR),0,1)
# error "namespace not properly defined"
#endif
This is the same idea as #HolyBlackCat's answer except that it's done in the preprocessor; the inner paste in the expression in the #if directive generates a token based on THENAMESPACE, pasting it to your required _API_H. If that token itself is defined in a macro, it will expand to a placemarker during the PASTE3 operation; this effectively pastes EMPTINESS_ [placemarker] DETECTOR, which is a macro expanding to a comma. That comma will shift the arguments of the indirect THIRD, placing 0 there, making the conditional equivalent to #if 0. Anything else won't shift the arguments, which results in THIRD selecting 1, which triggers the #error.
This also makes the same assumption HolyBlackCat's answer makes... that inclusion guards always look like #define BLA_API_H, but you can accommodate specific alternate styles using expanded pattern matching... for example, if you want to accept inclusion guards like #define BLAH_API_H 1 (who does that?), you could add #define EMPTINESS_1DETECTOR ,.
The language defines no way other than use of the defined operator or an equivalent to test whether identifiers are defined as macro names. In particular, a preprocessor directive of the form
#ifndef identifier
is equivalent to
#if ! defined identifier
(C11, 6.10.1/5). Similar applies to #ifdef.
The defined operator takes a single identifier as its operand, however, not an expression (C11, 6.10.1/1). Moreover, although the expression associated with an #if directive is macro expanded prior to evaluation, the behavior is undefined if in that context macro expansion produces the token "defined", and macro names modified by the defined unary operator are explicitly excluded from expansion (C11, 6.10.1/4).
Thus, although it is possible in many contexts to construct macro names via token pasting, and in such contexts the results are thereafter be subject to macro expansion, the operand of a defined operator is not such a context. The language therefore defines no way to test whether a constructed or indirectly-specified identifier is defined as a macro name.
HOWEVER, you can avoid relying on defined if you are in control of all the header guards, and you are willing to deviate slightly from traditional style. Instead of merely #defineing your header guards, define them to some nonzero integer value, say 1:
#if ! MYPREFIX_SOMEHEADER_H
#define MYPREFIX_SOMEHEADER_H 1
// body of someheader.h ...
#endif
You can then drop the defined operator from your test expression:
#if ! NAMESPACE(API_H)
# error "namespace not properly defined"
#endif
Do note, however, that the #define directive has a similar issue: it defines a single identifier, which is not subject to prior macro expansion. Thus, you cannot dynamically construct header guard names. I'm not sure whether you had that in mind, but if you did, then all the foregoping is probably moot.
In many places I see the usage of undefine macro before defining the same macro. For example:
#undef FORMULA
#ifdef SOMETHING
#define FORMULA 1
#else
#define FORMULA 2
#endif
What for the #undefine FORMULA used?
I may guess that it deals with the case when the macro was already defined before. But isn't the new definition overrides the old one? Thanks!
A macro name currently defined cannot be redefined with a different definition (see below), so #undef allows that macro name to be redefined with a different definition.
Here's the relevant legalese:
Both C and C++ Standards (same wording):
A macro definition lasts (independent of block structure) until a corresponding #undef directive is encountered or (if none is encountered) until the end of the preprocessing translation unit.
Slight differences in wording, same meaning:
C Standard (N1256), §6.10.3/2:
An identifier currently defined as an object-like macro shall not be redefined by another #define preprocessing directive unless the second definition is an object-like macro definition and the two replacement lists are identical. Likewise, an identifier currently defined as a function-like macro shall not be redefined by another #define preprocessing directive unless the second definition is a function-like macro definition that has the same number and spelling of parameters, and the two replacement lists are identical.
C++ Standard (N3337) §16.3/2
An identifier currently defined as an object-like macro may be redefined by another #define preprocessing directive provided that the second definition is an object-like macro definition and the two replacement lists are identical, otherwise the program is ill-formed. Likewise, an identifier currently defined as a function-like macro may be redefined by another #define preprocessing directive provided that the second definition is a function-like macro definition that has the same number and spelling of parameters, and the two replacement lists are identical, otherwise the program is ill-formed.
Same wording in both Standards:
Two replacement lists are identical if and only if the preprocessing tokens in both have the same number, ordering, spelling, and white-space separation, where all white-space separations are considered identical.
So:
#define X(y) (y+1)
#define X(z) (z+1) // ill-formed, not identical
IMHO, using #undef is generally dangerous due to the scoping rules for preprocessor macros. I'd prefer to get a warning or error from the preprocessor and come up with a different preprocessor macro rather than have some translation unit silently accept a wrong macro definition that introduces a bug into the program. Consider:
// header1.h
#undef PORT_TO_WRITE_TO
#define PORT_TO_WRITE_TO 0x400
// header2.h
#undef PORT_TO_WRITE_TO
#define PORT_TO_WRITE_TO 0x410
and have a translation unit #include both headers. No warning, probably not the intended result.
Yes, the new definition overrides all previous. But there is corresponding warning message. With #undef you have no warnings.
But isn't the new definition overrides the old one?
Yes, it does (when your compiler allows it). However, redefining a macro results in a compiler warning, which using #undefine lets you avoid.
This may be important in programming shops with strict rules on compiler warnings - for example, by requiring all production code to be compiled with -Werror flag, which treats all warnings as errors.
#undef removes the macro, so the name is free to be defined again.
If the macro was never defined in the first place, #undef has no effect, so there's no downside. #undef … #define should be read as replacing any potential previous definition, but not to imply that it must already be defined.
Popular compilers do allow you to skip the #undef, but this is not allowed by the official standard ISO C and C++ language specifications. It is not portable to do so.
I have doubts about macros, When we create like the following
#define DATA 40
where DATA can be create? and i need to know size also?and type of DATA?
In java we create macro along with data type,
and what about macro function they are all inline function?
Macros are essentially text substitutions.
DATA does not exist beyond the pre-processing stage. The compiler never sees it. Since no variable is created, we can't talk about its data type, size or address.
Macros are literally pasted into the code. They are not "parsed", but expanded. The compiler does not see DATA, but 40. This is why you must be careful because macros are not like normal functions or variables. See gcc's documentation.
A macro is a fragment of code which has been given a name. Whenever
the name is used, it is replaced by the contents of the macro. There
are two kinds of macros. They differ mostly in what they look like
when they are used. Object-like macros resemble data objects when
used, function-like macros resemble function calls.
You may define any valid identifier as a macro, even if it is a C
keyword. The preprocessor does not know anything about keywords. This
can be useful if you wish to hide a keyword such as const from an
older compiler that does not understand it. However, the preprocessor
operator defined (see Defined) can never be defined as a macro, and
C++'s named operators (see C++ Named Operators) cannot be macros when
you are compiling C++.
macro's are not present in your final executable. They present in your source code only.macro's are processed during pre-processing stage of compilation.You can find more info about macro's here
Preprocessor directives like #define are replaced with the corresponding text during the preprocessing phase of compilation, and are (almost) never represented in the final executable.
I am trying to compare to a defined constants in C, and I have simplified my program to the following:
#include "stdio.h"
#include "stdlib.h"
#define INVALID_VALUE -999;
int main(void)
{
int test=0;
if(test==INVALID_VALUE) //The error line..
return INVALID_VALUE;
return 0;
}
And when I use gcc to compile, it gives out error "error: expected ‘)’ before ‘;’ token".
Is there any reason that this cannot be done?
Remove the semicolon from your INVALID_VALUE definition.
Macros are replaced lexically (character-by-character) with no understanding of the syntax around them. Your macro INVALID_VALUE is set to -999;, so your if line expands the macro to:
if (test==-999;)
which is invalid C syntax.
You need to remove the ; in #define INVALID_VALUE -999;. See the fixed code.
You could have worked towards this conclusion by understanding what the error message expected ‘)’ before ‘;’ token was telling you. It's telling you that it expected to find a ) before the ; token, but from inspecting the line alone you don't see a ;. So maybe there's one in the definition of INVALID_VALUE? Look up at #define INVALID_VALUE -999; and there it is! Think it should be there, but not sure? So let's try remove it and see if it works. Success!
This page goes and explains why you shouldn't conclude a #define with a semicolon, even if it is needed in the use of the macro. It's good to learn as much as possible from your mistake so that you don't make it again. Quote:
Macro definitions, regardless of
whether they expand to a single or
multiple statements should not
conclude with a semicolon. If
required, the semicolon should be
included following the macro
expansion. Inadvertently inserting a
semicolon at the end of the macro
definition can unexpectedly change the
control flow of the program.
Another way to avoid this problem is
to prefer inline or static functions
over function-like macros.
In general, the programmer should
ensure that there is no semicolon at
the end of a macro definition. The
responsibility for having a semicolon
where needed during the use of such a
macro should be delegated to the
person invoking the macro.
The C Preprocessor Macro Language is Distinct from C
The ; in the macro definition should be removed.
This is an understandable mistake. If C were designed today, the macro language might be more integrated with the rest of C.
But on 16-bit machines in the early 1970's when C was invented, it was unwise to write an overly complicated program. It would end up useless as there would be no memory remaining to actually run the big masterpiece program, and even simple programs ran slowly.
So C was split into a rather simple macro preprocessor that was, originally, a completely separate program, and the compiler proper. The preprocessor program made no attempt to parse C beyond understanding the lexical analysis model.
When 32-bit machines took over, the preprocessor was typically integrated into the parser, but naturally the language needed to remain the same.
The semi colon at the end of
#define INVALID_VALUE -999;
Classic.
You do not need a semicolon after defining something. #define is actually a macro, and it will do an inline expansion on compile.
Thus,
#define IDENTIFIER 10;
int j = IDENTIFIER;
will expand as:
int j = 10;;
Change macro
from:
#define INVALID_VALUE -999;
to
#define INVALID_VALUE -999
Bye