Преобразование в нескалярную ошибку внутри макроса в C - PullRequest
0 голосов
/ 09 сентября 2018

У меня есть следующий код теста в C:

#include <stdio.h>
#include <stdlib.h>

typedef struct test {
    int a;
    int b;
} test_t;

#define test_init(test, a)                      \
    test = (test_t)calloc(1, sizeof(test_t));   \
    (test)->a = a;                              \
    (test)->b = (test)->a + 1;                  \

int main()
{
    test_t test;
    int a = 5;
    test_init(&test, a);

    return 0;
}

Но выдает следующую ошибку:

error: conversion to non-scalar type requested

Почему именно это случилось? Обратите внимание, что здесь нет обсуждения, использовать ли реальную функцию или макрос. Давайте просто предположим, что мы заинтересованы в макросах. Почему выдается указанная выше ошибка и как ее исправить?

1 Ответ

0 голосов
/ 09 сентября 2018

Напомним, что функционально-подобные макросы выполняют прямую подстановку своих параметров. Это означает, что это:

test_init(&test, a);

Получает преобразованный препроцессором в:

&test = (test_t)calloc(1, sizeof(test_t));
(&test)->a = a;
(&test)->b = (&test)->a + 1;

Обратите внимание, что в первой строке вы пытаетесь присвоить что-то &test. Результат оператора & не приводит к lvalue. Это означает, что вы не можете назначить что-то для &test, потому что это не представляет то, что вы можете назначить.

Чтобы это исправить, вам нужно объявить test в main как указатель:

test_t *test;
int a = 5;
test_init(test, a);

Или, если вы ожидаете, что макросу будет передан экземпляр типа test_t, вам не нужен вызов calloc:

#define test_init(test, a)                \
(test).a = a;                             \
(test).b = (test).a + 1;                  \
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...