It is possible to substring somehow a macro parameter?
I am facing the following problem. I have something like
#define READ(Name) structure.##Name.value
This macro will be called with something like PREFIX_Name and in the structure there are names without the PREFIX. So I need to take care of that prefix. How should I do that?
The best option is obviously not to call the macro like that. The second best option is to rename the struct members.
Failing the good options, the least bad option I can come up with is to write a macro per structure member:
#include <stdio.h>
typedef struct { int x; int y;} foo;
#define PREFIX_x_FIXER structure.x
#define PREFIX_y_FIXER structure.y
#define READ(Name) Name##_FIXER
int main (void)
{
foo structure;
READ(PREFIX_x) = 5;
printf("%d\n", READ(PREFIX_x));
}
Related
Consider the following program:
#include <stdio.h>
typedef struct structType {
int someVal;
int otherVal;
// ...more members used for other purposes
} structType;
void myFunc(structType * theStruct, int theVal) {
// Do something
}
int main()
{
structType myStruct;
myStruct.someVal = 5;
myStruct.otherVal = 10;
myFunc(&myStruct, myStruct.someVal);
myFunc(&myStruct, myStruct.otherVal);
return 0;
}
When calling myFunc() I need to pass both a pointer to the struct itself, and one of the values contained withing the struct.
Can I somehow make a macro so that myFunc() could be called something like:
MY_FUNC_MACRO(myStruct, someVal);
MY_FUNC_MACRO(myStruct, otherVal);
So that the struct pointer only needs to be typed once, and then the name of the member variable without passing the struct name once again.
I know about the stringilize macros like # an ##, but afaik that only goes from literal name to string. I need to go the other way, to somehow concatenate multiple strings into one literal name.
You don't need anything fancy
#define MY_FUNC_MACRO(A,B) (myFunc(&(A), (A).B))
works.
It's a little bit fragile though because B could be anything.
If you've got more nested structs and the middle layer is known at compile time, you can do this:
#define MY_FUNC_MACRO(A,B) (myFunc(&(A), (A).memberStruct.B))
I think you can simply use typedef like:
typedef structTypePointer *structType;
and the caller to function turn into:
myFunc(structTypePointer, myStruct.someVal);
or
myFunc(structTypePointer, structTypePointer->someVal);
I've searched for the answer to this, but its hard to find anything because the question is hard to phrase.
Lets say we have file1.h which defines a struct:
//file1.h
struct foo{
int param1;
...
};
Later I want to incorporate this foo struct into a general struct bar defined in a different file:
//file2.h
#include "file1.h"
struct bar{
struct foo foo1;
int param
...
}
I want it to be the same struct definition such that I dont have to modify two structs with the same parameters, and I dont want to use pointers since I have some serialization like routines that operate on bar. Also, I want foo to be defined in file1.h so I dont have to define it elsewhere every time I use the functions of file1. Is this possible, and is this even a good idea?
(I'm trying to achieve modularity where file1.c can be used either by itself or directly tied into the code in file2 without having to redefine structs everywhere)
This is very much possible and it is used everywhere.
//file2.h
#include "file1.h"
struct bar {
struct foo foo;
int param;
...
};
The #include directive tells the preprocessor to dump all contents of file1.h into file2.h.
And this is what you've been doing all along. You type #include <stdio.h> in order to grab the declerations of functions like printf, scanf. Naturally this works for structures, types and other things. You can even share variables if you do it correctly.
You need to make a couple of adjustments.
//file2.h
#include "file1.h" // <===================== include file here
struct bar {
struct foo var_foo; // <================ fix syntax here
int param
};
You will access the fields of struct foo embedded in struct bar as follows:
#include "file2.h"
int main() {
struct bar var_bar;
var_bar.var_foo.param1 = 0;
}
I am not trying to have two different structs with the same name, but rather defining the same exact struct two different times (probably in different header files).
For example:
struct foo {
int bar;
};
struct foo {
int bar;
};
gives an error.
The way to do this is to surround your struct with preprocessor instructions
#ifndef STRUCT_FOO
#define STRUCT_FOO
struct foo {
int bar;
};
#endif /* STRUCT_FOO */
#ifndef STRUCT_FOO
#define STRUCT_FOO
struct foo {
int bar;
};
#endif /* STRUCT_FOO */
this has the effect of only defining struct foo once. In combination with the commonly accepted practice of putting such an item in a file called foo.h, like so
#ifndef INCLUDE_FOO_H
#define INCLUDE_FOO_H
struct foo {
int bar;
};
#endif /* INCLUDE_FOO_H */
it also protects against a person doing
#include "foo.h"
#include "foo.h"
(rest of code)
As far as redefining the struct, that is not permitted in the C language; however, you can do some things that approximate a non-full redefine. I recommend avoiding them, as they tend to only make the code more obscure and difficult to maintain.
No.
There is absolutely no point in doing this. If you have a structure that is to be used by multiple compilation units, put it in a .h header file, and #include it from those .c files. Or, if you need it in multiple header files, just include the common header file from those.
Now if you don't need the actual structure definition, but rather just need to declare that it exists (so you can create pointers to said struture), you can use a forward declaration:
struct foo; // defined elsewhere
void somefunc(struct foo *ptr);
Short answer: No
The compiler isn't that smart - you already have struct foo, so you can't have another struct foo even if you think it is the same as the first one.
No.
You should seperate the struct in another header, it sounds like you may be organizing your code poorly and should rethink the design.
You could use a ifndef:
#ifndef NAMEDEF
struct name {
int val;
};
#define NAMEDEF
#endif
Although, I must reiterate that you need to rethink how your header files are designed and put this struct in a common header.
Its also possible to use a foreward declaration:
struct name;
void function() {
}
I'm new to C and I had a couple questions about getting struct values into a function and the correct way to declare the function.
in my common.h I've defined
extern struct ddrautocal;
int get_eeprom_vals(uchar); // is this the correct declare the function?
in calibration.c I define my struct and change some set some values (not shown)
#include <common.h>
struct ddrautocal {
u32 wdtr;
u32 clkp;
u32 rdcc;
};
in proc.c
#include <common.h>
int get_eeprom_vals(struct ddrautocal *cal){
// I'd like to access cal.wdtr and cal.clkp
}
I'm a complete derp, I know but I'm trying to get better. I've been trying to get this working all day and would like to know if I am declaring the function correctly in common.h and what is the correct way to access the ddrautocal struct in my get_eeprom_vals function located in proc.c Any help would be greatly appreciated. Thanks!
int get_eeprom_vals(uchar); signature is wrong.. It should be:
int get_eeprom_vals(struct ddrautocal *cal); So the signature of the forward declaration and function definition matches.
To access the members, you need: cal->wdtr, cal->clkp or (*cal).wdtr (*cal).clkp
-> uses the pointer indirection operator.
* is the combination of the indirection operator and the period - the dot - to access the field.
I also think you need #include "common.h" instead of #include <common.h> as common.h isn't a system header.
First thing to know is that we have to make sure that the declaration of a function and its definition match each other. In your case, the definition has the signature:
int get_eeprom_vals(struct ddrautocal *cal)
(A signature of a function includes its name and the argument list).
You need to replace the declaration with:
int get_eeprom_vals(struct ddrautocal *cal);
Also if you want to use period dot to derefer to a structure's members, you can declare your function as follows, and then you can refer to its members as what you showd
int get_eeprom_vals(struct ddrautocal cal);
{
// you can use cal.wdtr etc
}
Is there any way in standard C—or with GNU extensions—to append stuff to a macro definition? E.g., given a macro defined as
#define List foo bar
can I append bas so that it List expands as if I’d defined it
#define List foo bar bas?
I was hoping I could do something like this:
#define List foo bar bas
#define List_ Expand(List)
#undef List
#define List Expand(List_) quux
but I can’t figure out how to define the Expand() macro so it’ll do what I want.
Motivation:
I’m playing with discriminated/tagged unions along these lines:
struct quux_foo { int x; };
struct quux_bar { char *s; };
struct quux_bas { void *p; };
enum quux_type {quux_foo, quux_bar, quux_bas};
struct quux {
enum quux_type type;
union {
struct quux_foo foo;
struct quux_bar bar;
struct quux_bas bas;
} t;
};
I figure this is a good place for the X-macro. If I define a macro
#define quux_table X(foo) X(bar) X(bas)
the enumeration & structure can be defined thus, and never get out of sync:
#define X(t) quux_ ## t,
enum quux_type {quux_table};
#undef X
#define X(t) struct quux_ ## t t;
struct quux {
enum quux_type type;
union {quux_table} t;
};
#undef X
Of course, the quux_* structures can get out of sync, so I’d like to do something like this, only legally:
struct quux_foo { int x; };
#define quux_table quux_table X(foo)
struct quux_bar { char *s; };
#define quux_table quux_table X(bar)
struct quux_bas { void *p; };
#define quux_table quux_table X(bas)
(Well, what I really want to be able to do is something like
member_struct(quux, foo) { int x; };
but I’m well aware that macros cannot be (re)defined from within macros.)
Anyhow, that’s my motivating example. Is there a way to accomplish this?
Boost.Preprocessor examples are fine, if you can show me how to make the X-macro technique work with that library.
There is a way!
Using the new _Pragma keyword this can be achieved in gcc (though not with msvc)
If you pop a macro within it's own definition it will delay it's expansion until the macro is expanded for the first time. This allows you to make it's previous expansion part of it's own definition. However, since it is popped during it's expansion, it can only be used once
Here is some sample code to see it in action
#define pushfoo _Pragma("push_macro(\"foo\")") //for convenience
#define popfoo _Pragma("pop_macro(\"foo\")")
#define foo 1
pushfoo //push the old value
#undef foo //so you don't get a warning on the next line
#define foo popfoo foo , 2 //append to the previous value of foo
pushfoo
#undef foo
#define foo popfoo foo , 3
pushfoo
#undef foo
#define foo popfoo foo , 4
foo //this whole list will expand to something like popfoo foo popfoo foo popfoo foo , 4
//which will in turn expand to 1 , 2 , 3 , 4
foo //the second time this will expand to just 1
This option should make automatic code generation a fair bit easier, though unfortunately only on gcc (maybe clang, haven't tested)
To be honest there is no reason I can find why this must work, it is most probably undefined behavior that happens to work. I'm guessing the reason is that after popping foo, the current macro being expanded is no longer associated with the name foo which allows the symbol foo to be expanded, but that is only my conjecture
Edit:
After testing on clang, this does not does work on clang.
I don't know why I thought clang did not work, maybe it didn't on a different machine. I definitely did get it to work with the code given though
Effectively, no.
Macros are lazily evaluated. When you #define List_ Expand(List), its replacement list is the sequence of four tokens Expand, (, List, and ). There isn't any way to expand a macro into a replacement list.
All macro replacement takes place when a macro is invoked.
I'd recommend looking at using the Boost.Preprocessor library for automatic code generation. It's a bit of work, but you can accomplish some fairly impressive things using it. It should be fully compatible with C.
I'm not sure if this helps, but you can do vari arg macros. Mr. Conrad of the x264 project loves preprocessor abuse. If they sound like they might help you can find out more Here