C macro to get member of struct - c

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);

Related

How to capture a struct declaration in function

I have the following c code:
struct {
short s;
int n;
} variableName;
I want to write a function to capture this variable like so
void func(MyStruct* var){
//do stuff
}
func(&variableName);
I would like to do this without providing a definition for the struct. Is there a way to capture variableName?
No, you can't pass an "anonymous" struct into a function in C. You could of course define your function to accept the arguments individually:
void func(short s, int n) { ... }
Or you can define the MyStruct structure in a place that both the function and the calling code has visibility to. Note that the whole struct is passed by value (copy) when you do that, which may be the behavior you want here (or may not be).
You may be looking for something more like a "dictionary" or "associative array" or "hash" type that many other languages provide, with arbitrary key value pairs in it. Pure C does not have a facility for this; the compiler wants to know the layout of a structure in advance.
(I'm not sure if you might be asking about a slightly more esoteric idea, which is hiding the composition of a structure and passing around an "opaque handle" out of and into an API. There are ways to structure that in C, but please say so if that's what you're talking about.)
Completely overlooked "I would like to do this without providing a definition for the struct. Is there a way to capture variableName?" in the OP, unless it was edited after. The question makes less sense now, but heres how you could normally pass a struct to a function for future readers.
#include <stdio.h>
struct StructName{
short s;
int n;
};
void func(struct StructName struct_var){
printf("Param values are: %4X %4X\n", struct_var.s & 0xFFFF, struct_var.n & 0xFFFF);
}
int main(){
struct StructName struct_var;
struct_var.s = 0xDEAD;
struct_var.n = 0xBEEF;
func(struct_var);
}
//It looks like you are trying to use the definition as a variable. Here the definition is StructName and the variable is struct_var.
this sample code outputs:
Param values are: DEAD BEEF
If you use clang or gcc, you may be able to use typeof:
struct foo {
struct {
int i;
} anon;
} foo;
void do_something(typeof(foo.anon)* member) {
member->i = 1;
}
If there is no global instance of your type, you may be able to use typeof((struct foo){}.anon).
This comes with a lot of downsides. The most obvious ones are that:
it's not standard, and it ties you to clang/gcc
it's pretty darn ugly
it might not behave as you expect anyway
For instance, structurally-equivalent anonymous types do not have the same type, so in something like this:
struct foo {
struct {
int i;
} anon1;
struct {
int i;
} anon2;
} foo;
anon1 and anon2 both have a different type, meaning that typeof one of them cannot be used to refer to both.
In the long run, you will almost certainly find that it's worth naming the structures, especially if you use them as function arguments. For instance, if you want to make your variable available from a header, I think that you'll have to work pretty hard to keep it anonymous.
Although it's not particularly pretty and not compatible with C++, C puts the name of nested declarations in the global namespace, so this is portable and it's not a very big code change to front-load:
struct {
struct not_anon {
int i;
} anon;
} foo;
void do_something(struct not_anon* member) {
member->i = 1;
}

Substring macro parameter

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));
}

struct copy in c where struct are elements

Hi i have following situation
typedef struct
{
int a;
Name team[5];
Sport sport[5];
} School;
where Name and Sport are also structs,
typedef struct
{
char arry[20];
}Name;
typedef struct
{
char arry[20];
int tag;
}Sport;
then
School first_school, second_school;
I populate them individually, then at some point I do
first_school = second_school
But I step through code this line doesn't seem to work. How should I copy ?
But I step through code this line doesn't seem to work. How should I copy ?
It's entirely correct to copy struct like that
first_school = second_school; // valid
If it doesn't work as expected then the error is somewhere else. For example, you need to do strcpy() for string members.
Structures are values that can be assigned. They can contain arrays, which by themselves are not assignable, but being inside a struct makes it possible.
That code is fine, except you need to reverse the order of the declarations, since School references Name and Sport they must be declared first.
I tested it and it works just fine after reversing the declaration order, this prints hello:
int main(void) {
School foo, bar;
strcpy(bar.team[0].arry, "hello");
foo = bar;
printf("'%s'\n", foo.team[0].arry);
return 0;
}
There is probably something else wrong with your initialization of the second_shool, or you're failing to verify that it worked.
It will work for most members, but you have one that cannot be copied like that arry. You should copy one element at a time from the target to the destination instances.
Note that there are functions that take care of such copying like memcpy(). But you cannot copy an array by assignment like you do with an int or a struct actually.

How to pass a pointer to a struct declared inside another struct as a function parameter?

In one of my applications written in C I have a struct declared as a member of another struct:
struct _test
{
int varA;
//...
struct _small
{
int varB;
//...
} small;
} test;
Now I want to create a function that access varB above, but I don't want it to access the entire structure test, that is, I don't want to do:
#include <relevant_header>
void myFunction()
{
test.small.varB = 0;
}
instead, I want to pass only the small structure as a parameter to that function; something like this:
#include <relevant_header>
void myFunction(struct _test::_small* poSmall)
{
poSmall->varB = 0;
}
The problem is I don't know how to do this, that is, the above code doesn't compile right (I suppose it's C++ syntax only). So how may I do this in a C code - pass a pointer to a struct that was declared inside another struct? I wasn't able to find anything about this both in SO as well as in Google in general.
Just do:
void myFunction(struct _small *poSmall)
{
poSmall->varB = 0;
}
The scope of struct _small is not limited to its outer structure.

Modifying method to accept different type of parameters in C programming

typedef struct
{
char struct_variable_1a[10];
char struct_variable_1b[12];
} struct1;
typedef struct
{
char struct_variable_1a[10];
char struct_variable_1b[12];
int struct_variable_2c;
} struct2;
typedef struct1 *struct1_ptr;
typedef struct2 *struct2_ptr;
static void sampleFunction(struct1_ptr valueToInsert){
//this code does some stuff here
}
int main(){
struct1_ptr struct1_var = (struct1_ptr) malloc(sizeof(struct1));
strcpy(struct1_var->struct_variable_1a, "some value");
strcpy(struct1_var->struct_variable_1b, "some value");
sampleFunction(struct1_var);
return 0;
}
I have a sample code in C programming as shown above. In the main method, I am trying to pass a variable of type struct1_ptr for sampleFunction method call.
This works like a charm. But when I want to pass a variable of type struct2_ptr, the compiler is throwing error. Basically, I am java developer. I want to reuse this sampleFunction method for any variable type in its parameter in general. Kindly help me in this.
You could emulate inheritance in C like this:
typedef struct
{
char struct_variable_1a[10];
char struct_variable_1b[12];
} struct1;
typedef struct
{
struct1 parent; /* Must be first element! */
int struct_variable_2c;
} struct2;
And then call like this:
sampleFunction((struct1_ptr)ptr_to_struct2);
or (I would favor this, because there's no cast):
sampleFunction(&ptr_to_struct2->parent);
Just note that you won't be able to access members of struct2 in function without casting it back.
These work for simple structures, but if you do anything more complex, using C++ would be more approriate.
unfortunately C does not support method overloading / polymorphism. So you have to write your own methodology.
one is, to give the type as a first parameter to every overloaded function. Inside the function you walk along with a simple switch-case to jump to the original function implementation (like struct1_sampleFunction() and struct2_sampleFunction()).
another is, to put an RECORDCORE struct at the beginning of every struct and fill the type into this RECORDCORE, so each function can dispatch according to this data.
in both cases you have to change the prototype from "struct1_ptr value" to "void *value"
change your function from:
static void sampleFunction(struct1_ptr valueToInsert){
//this code does some stuff here
}
to:
static void sampleFunction(void* valueToInsert){
//this code does some stuff here
}
If you want to identify the type of the structure add a second parameter to your function that contains the size of the struct.
//Edit:
Inside the function you have to cast your variable back to the structure you want to use. for example:
strcpy(((struct1_ptr)valueToInsert)->struct_variable_1a, "some value");

Resources