Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C macro to return a Struct

Tags:

c

macros

struct

Is there a way to have a macro do exactly what this function does? I'm fairly new to C, any help is appreciated!

vector vectorScale(float c, vector *v){
    vector result = {v->x * c, v->y * c, v->z * c };
    return result;
}
typedef struct{
    float x,y,z;
}vector;

I'm currently trying this but getting errors:

#define vectorScale(vector v, vector c)    vector {float (v->x * c); float (v->y * c); float (v->z * c); }
like image 718
Abhishek Ravi Avatar asked Feb 05 '19 19:02

Abhishek Ravi


Video Answer


2 Answers

#define vectorScale(c, v) \
    ((vector) {(v)->x * (c), (v)->y * (c), (v)->z * (c) })

This construct, of the form (type) { initial values }, is called a compound literal. It is an object of the type.

However, with a decent compiler, it should serve to use a static inline function:

static inline vector vectorScale(float c, vector *v)
{
    return (vector) {v->x * c, v->y * c, v->z * c };
}

A good compiler should optimize this to be as efficient as the macro, and it avoids issues with v or c being expressions with side effects.

like image 185
Eric Postpischil Avatar answered Sep 29 '22 23:09

Eric Postpischil


macros arguments don't have a type. You want:

#define vectorSub(c,v) {(v)->x * (c), (v)->y * (c), (v)->z * (c) } 

That's the best equivalent unless someone calls your macro like this:

vector v2 = vectorSub(i++,v);

which is the common issue with macros using their parameters more than once because it will expand as:

{(v)->x * (i++), (v)->y * (i++), (v)->z * (i++) }

Complete self-contained and compiling example:

typedef struct  {
  float x,y,z;
} vector;

#define vectorSub(c,v) {(v)->x * (c), (v)->y * (c), (v)->z * (c) } 

vector foo()
{
  vector v = {0,3,4};
  vector v2 = vectorSub(12,&v);
  return v2;
}

note that a good compiler can/will inline such short functions, as your original vectorScale, specially if the inline keyword is used to send a hint the compiler (compiler doesn't necessarily comply) and the function is in the header file, so macros aren't the best choice here, specially since they don't involve macro trickery like token-pasting or stringing.

like image 31
Jean-François Fabre Avatar answered Sep 30 '22 01:09

Jean-François Fabre