Replace part of a function/variable name with C macros - c

I am writing some code that I will want to use multiple times with slightly different function and variable names. I want to replace part of the function and variable names with a macro. gcc filename.c -E shows that the substitution is not being made. How do I rectify this?
Here is some code from the file, before substitution:
#define _CLASS Object
#define POOLLEVEL1 1024
#define POOLLEVEL2 1024
typedef struct {
int Self;
int Prev;
int Next;
int In_Use;
//----data----//
//----function pointers----//
} Object;
_CLASS* _CLASS_Pool[POOLLEVEL1] = { 0 };
//Note on POOLLEVEL1, POOLLEVEL2: _CLASS_Pool[] is an array of pointers to arrays of type _CLASS. The number of objects in these arrays is LEVEL2, the maximum number of arrays of type object is LEVEL1; The arrays of type object are allocated when needed.
int _CLASS_Available_Head = -1;
int _CLASS_Available_Tail = -1;
//Start and finish of list of available objects in pool.
// More follows

The preprocessor operates on tokens. And when it comes to identifiers _CLASS is one token, while _CLASS_Pool is another entirely, since they are different identifiers. The preprocessor is not going to stop in the middle of parsing an identifier to check if part of it is another identifier. No, it will gobble up all of _CLASS_Pool before recognizing what the identifier is.
If you ever heard the preprocessor does pure textual substitution, that was a gross over-simplification. It operates on tokens, something best to always keep in mind.
So what you need is a mechanism by which the preprocessor accepts _CLASS as a token, expands it, and then pastes it to another token. Fortunately for you, those mechanisms already exist. It can be written as follows:
#define CONCAT(a, b) CONCAT_(a, b)
#define CONCAT_(a, b) a ## b
To be used like this:
_CLASS* CONCAT(_CLASS, _Pool)[POOLLEVEL1] = { 0 };
int CONCAT(_CLASS, _Available_Head) = -1;
/* and so forth */
The first CONCAT accepts your arguments, and forwards them to another function like macro. Forwarding them allows for any intermediate expansion, like _CLASS -> Object. Tokens that aren't object-like macros remains unchanged. CONCAT_ then simply applies the in-built token pasting operator. You can examine the result and tweak it further.
As an aside, the C standard reserves all identifiers that begin by an underscore, followed by an uppercase letter (_[A-Z][0-9a-zA-Z]*), to the implementation, for any use. Using them yourself leaves you open for undefined behavior. In general, try to avoid leading underscore in identifiers, unless you know all the rules for reserved identifiers by heart.

Related

Is it possible to determine the type of object on-line in one-pass, including macros?

I have a very simple parser that provides a small section of the C language; it looks at a well-formed translation unit and, with one pass and online, determine what the global symbols and types (function, struct, union, variable,) if one is not trying to trick it. However, I'm having trouble determining if it's a struct or a function in this example,
#define CAT_(x, y) x ## y
#define CAT(x, y) CAT_(x, y)
#define F_(thing) CAT(foo, thing)
static struct F_(widget) { int i; }
F_(widget);
static struct F_(widget) a(void) { int i;
return i = 42, F_(widget).i = i, F_(widget); }
int main(void) {
a();
return 0;
}
It assumes that the parenthesis is a function and parses this this way,
[ID<stati>, ID<struc>, ID<F_>, LPAR<(>, ID<widge>, RPAR<)>, LBRA<{>, RBRA<}>].
[ID<F_>, LPAR<(>, ID<widge>, RPAR<)>, SEMI<;>].
[ID<stati>, ID<struc>, ID<F_>, LPAR<(>, ID<widge>, RPAR<)>, ID<a>, LPAR<(>, ID<void>, RPAR<)>, LBRA<{>, RBRA<}>].
[ID<int>, ID<main>, LPAR<(>, ID<void>, RPAR<)>, LBRA<{>, RBRA<}>].
When in fact, what it thinks is the function at the top is actually a struct declaration and the top two should be concatenated. What is the simplest way to recognise that this?
Two-pass, emulating what actually happens in macro replacement; I would have to build a subset of the C pre-processor;
like the C lexer hack, except with macros;
backtrack with the semicolon at the end; that seems hard;
somehow recognise the difference at the beginning, (probably requiring me to add struct to my symbol table.)
As mentioned in the comments, if you want to be able to handle preprocessor macros, you will need to implement (or borrow) a preprocessor.
Writing a preprocessor mostly involves coming to terms with the formal description in the C standard, but it is not otherwise particularly challenging. It can be done online with the resulting token stream fed into a parser, so it doesn't really require a second pass.
(This depends on how you define a "pass" I suppose, but in my usage a one-pass parser reads the input only once without creating and rereading a temporary file. And that is definitely doable.)

Macros expansion using ## operator

Hi every one the problem is that i have in this macro
#define ADD_COMP(s1,s2,type)({\
int _x=0;\
for(int i=0;i<n_addrs;i++){\
if(memcmp(s1,&(s2->##type),6)!=0){\
_x=-1;\
}else{\
break;\
}\
}\
_x;\
})
s1 is a simple array and s2 is a structure with 4 vectors as members like this
typedef struct example{
char[6] one,
char[6] two,
char[6] three
}example;
Now for own reason i need to create a function that compares the s1 array of size 6 bytes with only a member of example, so for this purpose i wrote ADD_CMP using ## operator to be more generic as possible
So i defined:
#define one
#define two
#define three
and i used the function different times in this way hoping in the succes of macros expansion
ADD_COMP(some_array,example1,one)
ADD_COMP(some_array,example1,two)
ADD_COMP(some_array,example1,three)
but the compiler return as error:
error: pasting "->" and "one" does not give a valid preprocessing token
error: pasting "->" and "two" does not give a valid preprocessing token
error: pasting "->" and "three" does not give a valid preprocessing token
How can i fix it without write the same function for every structure member?
As the error suggests, there never was need for ##, as it is used to paste two preprocessing tokens to form a single one.
#define VAR(name, num) name##num
int VAR(foo, 1); // foo and 1 must be pasted together as foo1, instead of foo 1
The macro should compile with fixes to several syntax errors and missing declarations
#include<stdlib.h>
#include<string.h>
int n_addrs = 6;
#define ADD_COMP(s1,s2,type) {\
int _x=0;\
for(int i=0;i<n_addrs;i++){\
if(memcmp(s1,&(s2->type),6)!=0){\
_x=-1;\
}else{\
break;\
}\
}\
_x;\
}
typedef struct example{
char one[6];
char two[6];
char three[6];
}example;
void foo(void)
{
example* example1 = malloc(sizeof(example));
char some_array[6];
ADD_COMP(some_array,example1,one)
ADD_COMP(some_array,example1,two)
ADD_COMP(some_array,example1,three)
}
Note a compound statement { ... } isn't an expression and can not be used as such. By adding extra parentheses around it, you are using gnu's extension and is not standard C.
You should instead, just write a function to do this instead. You will then be able to return _x and with modern optimizers, there should be negligible to non-existant overhead.
The token pasting operator is designed for cases where you want to glue two different preprocessor tokens into a single token. For example, you might write something like
#define Glue(x) x my##x_
and then write
Glue(int);
to get this variable declaration:
int my_int;
Here, token-pasting combined the token “my_” with the token “int” to form the new token “my_int,” a new single token representing a name.
Once you paste two tokens together, the preprocessor doesn’t rescan them to figure out whether it’s a compound of several different individual tokens. It treats whatever is formed as a single token. For example, this code won’t compile:
#define BadAdd(x, y) x##+##y
int z = BadAdd(137, 42);
The issue here is that the token pasting forms a single preprocessing token 137+42. The preprocessor then tries to map this preprocessing token to a single logical token, but there’s no single token that this could correspond to. Normally, C or C++ would treat this as three separate tokens (137, +, and 42), but since you’ve forcibly glued them together the compiler has no idea what it’s looking at.
Contrast this with a more traditional Add macro, which for the purposes of exposition omits tons of important parentheses:
#define Add(x, y) x + y
int z = Add(137, 42);
Here, Add(137, 42) expands out to a sequence of three tokens (137, +, 42), which the compiler in a later phase can then interpret as an addition expression.
The macro you wrote above is like the BadAdd macro. By gluing the -> token together with a field name, you end up with a single unit like ->one that the compiler can’t meaningfully interpret as a single token. Just delete the ## here - just like going from BadAdd to Add, this will generate a sequence of tokens rather than a single token, which is what you want here.
I am not sure why you are attempting to use ##pre-processor token.
The macro can simply be:
#define ADD_COMP(s1, s2, member) ({\
int _x = 0;\
for (int i = 0; i < n_addrs; i++){\
if(memcmp(s1, &(s2.member), 6) !=0 ){\
_x = -1;\
} else {\
break;\
}\
}\
_x;\
})
and be used as:
ADD_COMP(some_array,example1,one);
ADD_COMP(some_array,example1,two);
ADD_COMP(some_array,example1,three);
More importantly, the macro looks easy enough that it can probably be replaced with a function, which is always a better option. I am not able to suggest how to transform the macro to a function since it's not clear to me where n_addrs comes from and where and how _x is used.

Resource Acquisition Is Initialization in C lang

The question is: Could you please help me understand better the RAII macro in C language(not c++) using only the resources i supply at the bottom of this question? I am trying to analyse it in my mind so as to understand what it says and how it makes sense(it does not make sense in my mind). The syntax is hard. The focus of the question is: i have trouble reading and understanding the weird syntax and its implementation in C language.
For instance i can easily read, understand and analyse(it makes sense to me) the following swap macro:
#define myswap(type,A,B) {type _z; _z = (A); (A) = (B); (B) = _z;}
(the following passage is lifted from the book: Understanding C pointers)
In C language the GNU compiler provides a nonstandard extension to
support RAII.
The GNU extension uses a macro called RAII_VARIABLE. It declares a
variable and associates with the variable:
A type
A function to execute when the variable is created
A function to execute when the variable goes out of scope
The macro is shown below:
#define RAII_VARIABLE(vartype,varname,initval,dtor) \
void _dtor_ ## varname (vartype * v) { dtor(*v); } \
vartype varname __attribute__((cleanup(_dtor_ ## varname))) = (initval)
Example:
void raiiExample() {
RAII_VARIABLE(char*, name, (char*)malloc(32), free);
strcpy(name,"RAII Example");
printf("%s\n",name);
}
int main(void){
raiiExample();
}
When this function is executed, the string “RAII_Example” will be displayed. Similar results can be achieved without using the GNU extension.
Of course you can achieve anything without using RAII. RAII use case it to not have to think about releasing ressources explicitly. A pattern like:
void f() {
char *v = malloc(...);
// use v
free v;
}
need you to take care about releasing memory, if not you would have a memory leak. As it is not always easy to release ressources correctly, RAII provides you a way automatize the freeing:
void f() {
RAII_VARIABLE(char*, v, malloc(...), free);
// use v
}
What is interesting is that ressource will be released whatever the path of execution will be. So if your code is a kind of spaghetti code, full of complex conditions and tests, etc, RAII lets you free your mind about releasing...
Ok, let's look at the parts of the macro line by line
#define RAII_VARIABLE(vartype,varname,initval,dtor) \
This first line is, of course, the macro name plus its argument list. Nothing unexpected here, we seem to pass a type, a token name, some expression to init a variable, and some destructor that will hopefully get called in the end. So far, so easy.
void _dtor_ ## varname (vartype * v) { dtor(*v); } \
The second line declares a function. It takes the provided token varname and prepends it with the prefix _dtor_ (the ## operator instructs the preprocessor to fuse the two tokens together into a single token). This function takes a pointer to vartype as an argument, and calls the provided destructor with that argument.
This syntax may be unexpected here (like the use of the ## operator, or the fact that it relies on the ability to declare nested functions), but it's no real magic yet. The magic appears on the third line:
vartype varname __attribute__((cleanup(_dtor_ ## varname))) = (initval)
Here the variable is declared, without the __attribute__() this looks pretty straight-forward: vartype varname = (initvar). The magic is the __attribute__((cleanup(_dtor_ ## varname))) directive. It instructs the compiler to ensure that the provided function is called when the variable falls out of scope.
The __attribute__() syntax is is a language extension provided by the compiler, so you are deep into implementation defined behavior here. You cannot rely on other compilers providing the same __attribute__((cleanup())). Many may provide it, but none has to. Some older compilers may not even know the __attribute__() syntax at all, in which case the standard procedure is to #define __attribute__() empty, stripping all __attribute__() declarations from the code. You don't want that to happen with RAII variables. So, if you rely on an __attribute__(), know that you've lost the ability to compile with any standard conforming compiler.
The syntax is little bit tricky, because __attribute__ ((cleanup)) expects to pass a function that takes pointer to variable. From GCC documentation (emphasis mine):
The function must take one parameter, a pointer to a type compatible
with the variable. The return value of the function (if any) is
ignored.
Consider following incorrect example:
char *name __attribute__((cleanup(free))) = malloc(32);
It would be much simpler to implement it like that, however in this case free function implicitely takes pointer to name, where its type is char **. You need some way to force passing the proper object, which is the very idea of the RAII_VARIABLE function-like macro.
The simplified and non-generic incarnation of the RAII_VARIABLE would be to define function, say raii_free:
#include <stdlib.h>
void raii_free(char **var) { free(*var); }
int main(void)
{
char *name __attribute__((cleanup(raii_free))) = malloc(32);
return 0;
}

How is typecasting parsed by C compilers?

Here it is syntactically impossible to tell whether f/g are function calls or typecasts without knowing how they are declared. Do compilers know the difference in the parse step, or do they usually resolve this in a second pass?
void f(int x){};
typedef short g;
int main(void){
((f)(1));
((g)(1));
return 0;
}
Very early versions of C (before the first edition of K&R was published in 1978) did not have the typedef feature. In that version of C, a type name could always be recognized syntactically. int, float, char, struct, and so forth are keywords; other elements of a type name are punctuation symbols such as * and []. (Parsers can distinguish between keywords and identifiers that are not keywords, since there are only a small and fixed number of them.)
When typedef was added, it had to be shoehorned into the existing language. A typedef creates a new name for an existing type. That name is a single identifier -- which is not syntactically different from any other ordinary identifier.
A C compiler must maintain a symbol table as it parses its input. When it encounters an identifier, it needs to consult the symbol table to determine whether that it's a type name. Without that information, the grammar is ambiguous.
In a sense, a typedef declaration can be thought of as creating a new temporary keyword. But they're keywords that can be hidden by new declarations in inner scopes.
For example:
{
typedef short g;
/* g is now a type name, and the parser has
* to treat it almost like a keyword
*/
{
int g;
/* now g is an ordinary identifier as far as the parser is concerned */
}
/* And now g is a type name again */
}
Parsing C is hard.
I think they do it lazily: whenever a token is parsed, the parsing of the next token is delayed until that symbol's semantic information is known. Then when the next token is parsed, the compiler already knows whether the symbol being referred to is a type name or not (it must have been declared earlier), and can act accordingly.
(So in this approach the semantic and syntactic analyses are intertwined and cannot be separated.)

Pointer to #define

I was just curious to know if it is possible to have a pointer referring to #define constant. If yes, how to do it?
The #define directive is a directive to the preprocessor, meaning that it is invoked by the preprocessor before anything is even compiled.
Therefore, if you type:
#define NUMBER 100
And then later you type:
int x = NUMBER;
What your compiler actually sees is simply:
int x = 100;
It's basically as if you had opened up your source code in a word processor and did a find/replace to replace each occurrence of "NUMBER" with "100". So your compiler has no idea about the existence of NUMBER. Only the pre-compilation preprocessor knows what NUMBER means.
So, if you try to take the address of NUMBER, the compiler will think you are trying to take the address of an integer literal constant, which is not valid.
No, because #define is for text replacement, so it's not a variable you can get a pointer to -- what you're seeing is actually replaced by the definition of the #define before the code is passed to the compiler, so there's nothing to take the address of. If you need the address of a constant, define a const variable instead (C++).
It's generally considered good practice to use constants instead of macros, because of the fact that they actually represent variables, with their own scoping rules and data types. Macros are global and typeless, and in a large program can easily confuse the reader (since the reader isn't seeing what's actually there).
#define defines a macro. A macro just causes one sequence of tokens to be replaced by a different sequence of tokens. Pointers and macros are totally distinct things.
If by "#define constant" you mean a macro that expands to a numeric value, the answer is still no, because anywhere the macro is used it is just replaced with that value. There's no way to get a pointer, for example, to the number 42.
No ,It's Not possible in C/C++
You can use the #define directive to give a meaningful name to a constant in your program
We can able to use in two forms.
Please : See this link
http://msdn.microsoft.com/en-us/library/teas0593%28VS.80%29.aspx
The #define directive can contain an object-like definition or a function-like definition.
Iam sorry iam unable to provide one more wink ... Please see the IBM links..since below i pasted linke link
u can get full info from above 2 links
There is a way to overcome this issue:
#define ROW 2
void foo()
{
int tmpInt = ROW;
int *rowPointer = &tmpInt;
// ...
}
Or if you know it's type you can even do that:
void getDefinePointer(int * pointer)
{
*pointer = ROW;
}
And use it:
int rowPointer = NULL;
getDefinePointer(&rowPointer2);
printf("ROW==%d\n", rowPointer2);
and you have a pointer to #define constant.

Resources