Is it necessary to undef macros within function? - c

I've seen many times code like this:
void func(){
#define a ...
...
#undef a
}
Is the #undef necessary at all?

It is not necessary, but the scope of a #define is global after the line it was defined. It will not obey the function scope, if you are thinking it will.

It's not necessary. If the macro is meant to be used only inside the function, it's probably a good idea to #undef it. If you don't, that just means that the macro remains visible through the rest of the translation unit (source file).
Most macros are probably intended to be visible throughout a source file anyway, so usually the question doesn't arise.

When i declare a macro like you did inside the body of a function then i would #undef it at the end. Because most probably it is meant for that function body only.
In general it is always a good idea to #undef a macro when you know that the macro definition is not going to be used anytime later because the macro definition propagate to all other files which include the file having a macro.

That depends. It is only necessary if you want to ensure that a will not be potentially available at later points in your program depending on your logic. The define is now global (in the current translation unit)!
From gnu.org:
If a macro ceases to be useful, it may be undefined with the `#undef'
directive.
Additionally,
Once a macro has been undefined, that identifier may be redefined as a
macro by a subsequent `#define' directive. The new definition need not
have any resemblance to the old definition.
and
However, if an identifier which is currently a macro is redefined,
then the new definition must be effectively the same as the old one.
Two macro definitions are effectively the same if:
Both are the same type of macro (object- or function-like).
All the tokens of the replacement list are the same.
If there are any parameters, they are the same.
Whitespace appears in the same places in both. It need not be
exactly the same amount
of whitespace, though. Remember that comments count as
whitespace.

Related

#define FOO(x) bar, x never referenced in definition, what happens?

I found some legacy code with something similar to the following. Say I have the following definition:
#define FOO(x) bar
x is never referenced in the definition. So, does that mean that whatever text is placed within FOO() is irrelevant?
The code I'm looking at is scattered with calls such as FOO(someValue); I'm assuming the preprocessor is replacing the entire statement with simply bar, no matter what someValue is? A little thrown off by why x is present at all.
Yes, FOO(whatever) is completely replaced with bar in your example.
Macros like this are often seen in "configure-able" code, like:
#if defined(ENABLE_DEBUG_PRINT)
#define DEBUG_PRINT(msg) printf("Here's a message: %s\n", msg)
#else
#define DEBUG_PRINT(msg) /* empty */
#endif
Nothing special happens. Any occurrence of x in the macro definition is expanded to the value of the corresponding argument when the macro is expanded. If there is no such occurrence, it's not expanded (and the actual value of the argument is irrelevant).
As for why it's there, it may be that some past or potential future version of the macro might make some use of the argument. Perhaps it's one of several macros that take a single argument, and it's defined that way for consistency. It's impossible to tell without more context. But the macro definition is perfectly valid.
What happens is exactly what you thought would happen—the value is ignored.
I recommend running the preprocessor (gcc -E or cpp (possibly add -x c++ for c++)) to actually see what actually happens on your implementation instead of just guessing.
Yes, macro FOO() expands to bar regardless of its argument. This is not different in nature from how a function can ignore some or all of its parameters.
The macro may be a place holder for a possible future implementation that does use its argument, or a replacement for an older implementation that did. It may also be that the definition of macro FOO() is different in different places, and that some of the definitions use their argument. If it isn't any of those, nor similar, then it's just obfuscatory.
So, does that mean that whatever text is placed within FOO() is irrelevant?
Unless there's a conditionally-compiled alternative version of FOO() where x is actually used. You might that to only evaluate the expression x in the debug build, for instance.
This statement just consumes the x expression without using it.
For instance, if you want to stub some methods you can use that.

Where macros variable created? and size of the variable?

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.

why macro does not work in this situation?

I have the code follow:
funcA() {
#define strdup(a) NULL
funcB();
}
While funcB() in another file. I find that the marco strdup(a) does not work.How can I make it work?
I assume funcB uses strdup, otherwise your question doesn't make sense.
Macros are only relevant in the preprocessor and do not propagate to different compilation units. If funcB is in a different compilation unit then the macro needs to be defined there too, this is generally achieved through including a header with the macro into all compilation units that need it.
It does not work because, the source file containing funcB has no knowledge of your macro.
Macro are expanded during the preprocessing and do not propagate to different translation unit. That is, a common way to solve this problem is to put the macro definition inside a header file. Included by every source file which need the macro definition.
Also from the C standard:
6.10.3.5 Scope of macro definitions
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. Macro definitions have no significance after translation phase 4.
So it doesn't take in count the function scope.

Setting the scope of a MACRO

I have a general doubt ..
Is there a way we limit the scope of a MACRO within a .C file just like a static function ?
Macros are done by the pre-processor.
The pre-processor reads all files being processed and applies macros and macro logic, the results of which are then passed to the compiler.
Once a macro is defined, its value will be used everywhere the macro is referenced, even in other files.
Please see the GCC Documentation for details regarding macro usage.
The general practice is to #undef the macro when you're done with it. Error prone, but it works.
Macros don't have any sort of block scope.
You can place the macro in the .c file where you want it to be used instead of a header file and it won't be accessible from other files (although some compilers allow inclusion of .c files but no one does that, well no one that's sensible).
Also mentioned below is the use of #undef but that can quickly start to get messy if you use that macro a lot.
All macros are already like static functions, in that they can only be used in the translation unit in which they're defined. If you want to restrict the areas where you can use a particular macro, just define it in a sensible place.
a macro is evaluated by the preprocessor, not by the compiler.
it doesn't know anything about compilation units, so you cannot restrict it's use to one.
instead it is evaluated within the translation unit.
the macros life cycle starts in the line it is defined (all lines above it do know nothing about the macro), and it ends either at the end of the translation unit or whenever it get's undefined using "#undef"
All C macros are limited to the translation unit (a single C file) unless they are defined in a header and being included to every translation units.
Unfortunately, a translation unit is often big, easily hundreds to thousands of lines of code, and macros are context dependent and it would be much more useful if it can be limited to much smaller context (such as a block scope). Lacking scope limits macro usage in C, mostly global constants, a few universal simple routines, and often need all capital names or some trick to manage pollutions).
However, higher order functions can be easily achieved with macros. Think about how we use natural language, where we may use "it" to refer any thing too long to repeat within the context. A scoped macro system will enable the same ability.
I have developed MyDef, which is essentially a scoped macro system.

#include inside the main () function

I would like to know if it's possible that inside the main() function from C to include something.
For instance, in a Cell program i define the parameters for cache-api.h that later in the main() function i want to change .
I understood that what was defined with #define can be undefined with #undef anywhere in the program, but after redefining my needed parameters I have to include cache-api.h again . Is that possible?
How can I solve this problem more elegant ? Supposing I want to read from the main storage with cache_rd(...) but the types would differ during the execution of a SPU, how can i use both #define CACHED_TYPE struct x and #define CACHED_TYPE struct y in the same program?
Thanks in advance for the answer, i hope i am clear in expression.
#define and #include are just textual operations that take place during the 'preprocessing' phase of compilation, which is technically an optional phase. So you can mix and match them in all sorts of ways and as long as your preprocessor syntax is correct it will work.
However if you do redefine macros with #undef your code will be hard to follow because the same text could have different meanings in different places in the code.
For custom types typedef is much preferred where possible because you can still benefit from the type checking mechanism of the compiler and it is less error-prone because it is much less likely than #define macros to have unexpected side-effects on surrounding code.
Yes, that's fine (may not be the clearest design decision) but a #include is just like a copy-and-paste of that file into the code right where the #include is.
#define and #include are pre-processor macros: http://en.wikipedia.org/wiki/C_preprocessor
They are converted / inlined before compilation.
To answer your question ... no, you really wouldn't want do do that, at least for the sake of the next guy that has to try and unscramble that mess.
You can #include any file in any file. Whether it is then valid depends on the content of the file; specifically whether that content would be valid if it were entered directly as text.
Header files generally contain declarations and constructs that are normally only valid outside of a function definition (or outside any kind of encoding construct) - the clue is in the name header file. Otherwise you may change the scope of the declarations, or more likley render the compilation unit syntactically invalid.
An include file written specially for the purpose may be fine, but not just any arbitrary header file.
General purpose header files should have include guards to prevent multiple declaration, so unless you undefine the guard macro, re-including a header file will have no effect in any case.
One possible solution to your problem is to create separately compiled modules (compilation units) containing wrapper functions to the API you need to call. Each compilation unit can then include the API header file after defining the appropriate configuration macros. You will then have two separate and independent interfaces provided by these wrapper functions.

Resources