why macro does not work in this situation? - c

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.

Related

What does #define without assignment assign to in C?

I have often seen code like
#ifndef HEADERFILE_H
#define HEADERFILE_H
// some declarations in
// the header file.
#endif
I want to know what #define HEADERFILE_H define HEADERFILE_H to?
I tried doing
cout<<HEADERFILE_H<<endl;
but I am getting
error: expected expression
A define preprocessing directive has the form # define identifier preprocessing-tokens, ending with a new-line character. The preprocessing-tokens is a list of zero or more preprocessing tokens. It may be empty, that is, it may have zero tokens. This means, that when the identifier is encountered in a place where macro replacement occurs, it will be replaced with nothing.1
Tests of the form #ifdef identifier, #ifndef identifier, or define identifier in a #if or #elif directive test whether identifier is defined or not. If it was not defined (or its definition was removed with the #undef directive), then the test indicates it is not defined. If it was defined, then the test indicates it was defined, even if the definition is for zero tokens.
A definition with zero tokens is different from no definition at all, and defined identifier will evaluate as true for the former and false for the latter.
Footnote
1 If the list does have tokens, then identifier will be replaced with those tokens and # and ## operators among them will be applied. A preprocessing token is largely an identifier (like foo34), a constant (like 3, 4u, or 1.8e4), one of the C operators or special characters (like * or +=), or certain other components of the C language.
It actually defines "nothing else than itself". That is: you may define a macro without assigning it a specific value. Since you can check if a given macro is defined or not, you therefore can ask for the simple "existence" of a given macro.
This is useful to indicate a context (for example, if you're compiling for a given OS) and/or the availability of some resources.
In this particular example, this is a called a "guard": it will define itself if this hasn't been done first before, as well as including the rest of the file, which is totally embedded in the #ifdef … #endif clause.
This is used to implement a kind of require_once, that is something that will be included if needed, but not multiple times. This is required when you are defining functions or declaring variables at a global scope, for instance.
This is a language idiom (I will comment it):
#ifndef HEADERFILE_H
Between this, and the last #endif everything is included in compilation, but only if HEADERFILE_H has not been defined before.
#define HEADERFILE_H
The first thing we do in the block is to #define the identifier, so next time we find this fragment again later, the contents between #ifndef and #endif will not be #included again (because of the identifier declaration).
// some declarations in
// the header file.
this block will be included only once, even if you #include this file several times.
#endif
and this marks the end of the protected block.
It is common to include some file that, indeed, #includes another, and that file includes another, leading to a point in which you don't know which files have been included and which don't. This phrasing allows you to be protected, and to be able to #include the same file several times (normally you cannot, as some definitions cannot be repeated in the same compilation unit, e.g. declarations) the lines above will include the contents and define the identifier, making next inclussions (that are effectively done) not to include the contents, as the identifier appears as #definen in second and ulterior times.

Using #undef before #define

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.

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.

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.

Is it necessary to undef macros within function?

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.

Resources