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.
Related
I am building some generic things in C.
Here is the code:
// main.c
#include <stdio.h>
#define T int;
#include "test.h"
int main()
{
return 0;
}
// test.h
#define _array_is_pointer(T) ( \
{ \
T _value; \
__builtin_classify_type(_value) == 5; \
})
#ifdef T
#if _array_is_pointer(T)
struct array_s
{
T *items;
}
void array_push(struct array_s * array, T value)
{
// push method for pointer.
}
#else
struct array_s
{
T *items;
}
void array_push(struct array_s * array, T value)
{
// push method for non-pointer.
}
#endif
#endif
** edited: add more code in test.h **
I would like the preprocessor runs different code when T is pointer or non-pointer.
But I got an error token "{" is not valid in preprocessor expressions.
Is it possible to do that?
I would like the preprocessor runs different code when T is pointer or non-pointer.
Is it possible to do that?
No, it is not possible. Preprocessor is not aware of types.
If you really want this, pass a mark if T is a pointer or not as a separate macro.
#define T int*
#define T_IS_A_POINTER 1
#include "test.h"
Or have separate calls:
#define T int*
#include "test_a_pointer.h"
#define T int
#include "test_not_a_pointer.h"
The preprocessor doesn't know whether T is a pointer, because preprocessing happens before semantic analysis of the program. All the preprocessor sees are tokens; it knows that 42 is a number and take42, but that's it. The only definitions it knows about are preprocessor #defines.
Moreover, in C, functions --even builtin constant functions like sizeof and __builtin_classify_type-- cannot be evaluated by the preprocessor. The preprocessor cannot evaluate block expressions either, but there wouldn't be much point so it has no idea what a variable is and thus doesn't need declarations. The only identifier you can use in an #if preprocessor conditional are macro definitions which expand to integer constants (or entire expressions containing only arithmetic operations on integer constants).
There is the _Generic construct introduced in C11, which allows you to generate different expressions based on the type of a controlling expression. But it can only be used to generate expressions, not declarations, so it's probably not much help either.
There is no issue while writing multi-line code-snippet in
#define _array_is_pointer(T) ( \
{ \
T _value; \
__builtin_classify_type(_value) == 5; \
})
But, as you have know, the first step done before passing the code to compiler is to create an Expanded source code. In this step, all the five lines woud be pasted whereever you would have written _array_is_pointer(T) and hence resulting code would have :
#if (
{
T _value;
__builtin_classify_type(_value) == 5;
})
and here is a blunder. One can not write multiple lines like this in if clause, nor you could do this using {}. And hence, you got the error token "{" is not valid in preprocessor expressions.
Hence, you would have to write a single expression to in if clause preprocessor.
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.
I am trying to do some template stuff in C:
I need to create a 2d-vector struct with functions to work with them and I need to have them for the types int, unsigned int, float, double and maybe even other types that all support basic math functionality.
I could write all the code for every type. If I write an bug in one of them, I may forget to fix the bug in all others. I did it before in C++ and I just used templates, but now that I want it in C (C11)... there are none.
So I look at macro's, and I see that it is possible to use the ## tag to literally use the macro's passed parameter.
Here's some code I tried:
#define DECLARE_VEC2(N, T) \
typedef struct { T x, y;} N; \
inline N *##N_new() { return malloc(sizeof(N));}
DECLARE_VEC2(vec2i, int);
DECLARE_VEC2(vec2f, float);
DECLARE_VEC2(vec2d, double);
It doesn't work. The ##N is not replaced with vec2i/vec2f/vec2d but just remains ##N or even simply N. The compiler won't accept it and when I run gcc with the -E flag on the file, I see that the preprocessor indeed doesn't replace it.
If, however, I add a space between ##N and the _new, the preprocessor does replace it, but the space is also there which obviously gives problems when compiling it.
If, however, I change the function name to new_##N, it not only preprocesses fine, but is also working flawlessly.
BUT I DON'T WANT THE LATTER!
I create all my structs with functionality this way: typename_function() and don't want to change it because of this stupid problem.
So, the question is: is there a way to solve this?
Note: I also tried stuff like adding an extra parameter to the macro containing the underscore, or even declaring a macro within the macro adding the underscore, but they all come to the same problem: there is need for some kind of separator that makes the preprocessor understand that the name ends before the underscore or whatever is behind it.
Edit: strangely enough, when using something like ##N##_new(), the preprocessor replaces the name fine, but then won't accept it with errors like:
error: pasting "*" and "vec2i" does not give a valid preprocessing token
inline N * ##N##_new() { return malloc(sizeof(N));}
although the resulting code seems to be correct (gcc -E):
typedef struct { int x, y;} vec2i; inline vec2i *vec2i_new() { return malloc(sizeof(vec2i));};
## is not a prefix operator, it's an infix one — a binary concatenation operator similar to +. So you'd use it like this:
#define DECLARE_VEC2(N, T) \
typedef struct { T x, y;} N; \
inline N * N##_new() { return malloc(sizeof(N));}
Note that whitespace around ## is ignored, so if you consider it more readable, you can also do this for identical effects:
#define DECLARE_VEC2(N, T) \
typedef struct { T x, y;} N; \
inline N * N ## _new() { return malloc(sizeof(N));}
This should also explain why you were getting the error "does not give a valid preprocessing token": you were effectively trying to concatenate * and int into a single token.
I have the following lines of code, created by a database export program:
typedef struct _s8_VARB
{
unsigned char _byte[8];
} s8_VARB;
const s8_VARB varb00[] = {
mMM(1,25,22,12,0,0,0,0,27)
mMM(0,1,29,12,0,0,0,0,21)
mMM(1,1,36,12,0,0,0,0,22)
}
The mMM is a macro that I want to define with a functionality that will produce the following data during compilation:
const s8_VARB varb00[] = {
1,25,22,12,0,0,0,0,27,
1,1,36,12,0,0,0,0,22,
}
So it basically should check the 1st parameter. If it is 0, that complete line should omitted. If it is 1, all the parameters (except the 1st) should be 'put on the line', ending with a comma.
What I have tried is this:
#define COMMA ,
#define mMM(cond, a,b,c,d,e,f,g,h) (cond) ? (a),(b),(c),(d),(e),(f),(g),(h) COMMA :
But this is not working. Not even compiling, as gcc complains:
error: expected expression before ':' token
How should this macro definition should look like? Is this possible at all in C?
You can initialize an array with constant data only. A conditional statement is by definition not constant (even if it's known to the compiler at compile time).
Instead you could do it like this:
#define _mMM0(...)
#define _mMM1(...) {__VA_ARGS__},
#define mMM(cond, ...) _mMM##cond(__VA_ARGS__)
const unsigned char varb00[][8] = {
mMM(1,25,22,12,0,0,0,0,27)
mMM(0,1,29,12,0,0,0,0,21)
mMM(1,1,36,12,0,0,0,0,22)
};
I removed the struct and replaced it with its only member directly. In case C99 is not available, you can name every parameter as you used to do.
Here's a hackish solution. If the number of arguments is fixed and you can't use C99+, then you could list them explicitly instead of using ... and __VA_ARGS__.
#define mMM(x, ...) mMM##x(__VA_ARGS__)
#define mMM0(...)
#define mMM1(...) __VA_ARGS__,
The ## operator pastes the token mMM and the x argument together to form a new macro name -- either mMM0 or mMM1 -- which is then called with the remaining arguments. mMM0() in turn expands to nothing, and mMM1() expands to its arguments.
(The extra trailing comma after the last element won't be a problem by the way. int a[] = { 1, 2, 3, } is explicitly allowed syntax in C.)
As a side note, invoking a macro like
#define m(x) (x) ? 1 : 2
using e.g. m(0) will simply expand it to (0) ? 1 : 2. The ternary operator will not be handled in the preprocessor.
I'm currently working on a project, and a particular part needs a multi-line macro function (a regular function won't work here as far as I know).
The goal is to make a stack manipulation macro, that pulls data of an arbitrary type off the stack (being the internal stack from a function call, not a high-level "stack" data type). If it were a function, it'd look like this:
type MY_MACRO_FUNC(void *ptr, type);
Where type is the type of data being pulled from the stack.
I currently have a working implementation of this for my platform (AVR):
#define MY_MACRO_FUNC(ptr, type) (*(type*)ptr); \
(ptr = /* Pointer arithmetic and other stuff here */)
This allows me to write something like:
int i = MY_MACRO_FUNC(ptr, int);
As you can see in the implementation, this works because the statement which assigns i is the first line in the macro: (*(type*)ptr).
However, what I'd really like is to be able to have a statement before this, to verify that ptr is a valid pointer before anything gets broken. But, this would cause the macro to be expanded with the int i = pointing to that pointer check. Is there any way to get around this issue in standard C? Thanks for any help!
As John Bollinger points out, macros expanding to multiple statements can have surprising results. A way to make several statements (and declarations!) a single statement is to wrap them into a block (surrounded by do … while(0), see for example here).
In this case, however, the macro should evaluate to something, so it must be an expression (and not a statement). Everything but declarations and iteration and jump statements (for, while, goto) can be transformed to an expression: Several expressions can be sequenced with the comma operator, if-else-clauses can be replaced by the conditional operator (?:).
Given that the original value of ptr can be recovered (I’ll assume "arithmetic and other stuff here" as adding 4 for the sake of having an example)
#define MY_MACRO_FUNC(ptr, type) \
( (ptr) && (uintptr_t)(ptr)%4 == 0 \
? (ptr) += 4 , *(type*)((ptr) - 4) \
: (abort() , (type){ 0 }) )
Note, that I put parentheses around ptr and around the whole expression, see e.g. here for an explanation.
The second and third operand of ?: must be of the same type, so I included (type){0} after the abort call. This expression is never evaluated. You just need some valid dummy object; here, type cannot be a function type.
If you use C89 and can’t use compound literals, you can use (type)0, but that wouldn’t allow for structure or union types.
Just as a note, Gcc has an extension Statements and Declarations in Expressions.
This is very nasty:
#define MY_MACRO_FUNC(ptr, type) (*(type*)ptr); \
(ptr = /* Pointer arithmetic and other stuff here */)
It may have unexpected results in certain inoccuous-looking circumstances, such as
if (foo) bar = MY_MACRO_FUNC(ptr, int);
Consider: what happens then if foo is 0?
I think you would be better off implementing this in a form that assigns the popped value instead of 'returning' it:
#define MY_POP(stack, type, v) do { \
if (!stack) abort_abort_abort(); \
v = *((type *) stack); \
stack = (... compute new value ...); \
} while (0)