Макрос C для возврата Struct - PullRequest
0 голосов
/ 05 февраля 2019

Есть ли способ заставить макрос делать именно то, что делает эта функция?Я довольно новичок в C, любая помощь приветствуется!

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;

Я сейчас пытаюсь это, но получаю ошибки:

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

Ответы [ 2 ]

0 голосов
/ 05 февраля 2019
#define vectorScale(c, v) \
    ((vector) {(v)->x * (c), (v)->y * (c), (v)->z * (c) })

Эта конструкция вида (type) { initial values } называется составным литералом.Это объект type.

. Однако, при хорошем компиляторе он должен использовать статическую встроенную функцию:

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

Хороший компилятор должен оптимизировать это, чтобыстоль же эффективен, как и макрос, и позволяет избежать проблем, когда v или c являются выражениями с побочными эффектами.

0 голосов
/ 05 февраля 2019

аргументы макроса не имеют типа.Вы хотите:

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

Это лучший эквивалент, если кто-то не называет ваш макрос следующим образом:

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

, что является распространенной проблемой с макросами, использующими свои параметры более одного раза, поскольку он будет расширятьсяas:

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

Полный автономный пример компиляции:

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

обратите внимание, что хороший компилятор может / будет встроить такие короткие функции, как ваш оригинальный vectorScale, особенно еслиключевое слово inline используется для отправки подсказки компилятору (компилятор не обязательно соответствует), а функция находится в заголовочном файле, поэтому макросы здесь не лучший выбор, особенно потому, что они не включают трюки с макросами, такие каквставка токенов или цепочка.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...