Я застрял с этой ошибкой:
cities.c: In function ‘main’:
cities.c:7:48: error: dereferencing pointer to incomplete type ‘struct Graph’
printf("well, it got here. nodeCount: %d\n", x->nodeCount);
Все другие решения указывают на то, что имена написаны с ошибками и, следовательно, не определены, однако, если я перенесу определение struct Graph
в заголовок, оно будет работать нормально.
Раньше я использовал эту механику в другой моей библиотеке, и она до сих пор отлично компилируется, я потратил часы, пытаясь переместить вещи, но безрезультатно.
график.ч:
#ifndef GRAPH_H
#define GRAPH_H
typedef struct Graph * Graph;
int graphCreate(Graph*, int);
int graphAddPath(Graph, int, int, unsigned int);
int graphRemovePath(Graph, int, int);
int graphDestroy(Graph*);
#endif /* GRAPH_H */
graph.c: https://pastebin.com/FzkaJJwP
города.с:
#include "graph.h"
#include <stdio.h>
int main() {
Graph x;
graphCreate(&x, 5);
printf("well, it got here. nodeCount: %d\n", x->nodeCount);
}
Output is as expected in my library at https://git.mif.vu.lt/emiliskiskis/c_deck.
Спасибо за помощь.
Укажите минимальный воспроизводимый пример
Вы не можете получить доступ к полям незавершенных структур, struct Graph
здесь неполный.
Откуда компилятору знать о члене nodeCount
, если вы скрываете определение структуры?
Определение struct Graph
находится в файле graph.c
. Когда вы компилируете файл cities.c
, это определение не отображается. Вам нужно переместить определение в graph.h
struct Graph {
unsigned int **matrix;
int nodeCount;
};
Как предложил Блэйз, приведенное ниже определение сбивает с толку. typedef struct Graph * Graph
. Лучшим решением было бы
typedef struct Graph Graph;
а затем в коде вы можете использовать
int graphCreate(Graph **, int);
int graphAddPath(Graph *, int, int, unsigned int);
int graphRemovePath(Graph *, int, int);
int graphDestroy(Graph **);
Привет, это была моя личная библиотека (не для совместного использования), поэтому я просто знаю, что происходит, но спасибо за предложение. Я написал функцию для возврата количества узлов, и она работает. Большое спасибо, а также @HolyBlackCat и @Gerhardh!
Сообщение компилятора довольно ясно. Тип является неполным, что в основном означает, что компилятор знает только о существовании структуры с именем Graph, но не знает, как она выглядит. Следствием этого является то, что вы не можете получить доступ к полям.
Итак, сначала вы должны ответить на этот вопрос. Вы хотите, чтобы программист, использующий библиотеку, имел доступ к полям Graph? Если нет, поместите определение в файл .c. Если да, поместите определение в файл .h.
Еще одна вещь, которую следует учитывать, это typedef struct Graph * Graph
. Вы скрываете очень много информации при определении типа структуры, и то же самое происходит, когда вы определяете тип указателя. Теперь вы делаете и то, и другое. Мое личное мнение таково, что вам действительно следует избегать этого, если только ответ на приведенный выше вопрос не будет «нет».
Мое предложение: если вы хотите, чтобы пользователь библиотеки мог получить доступ к полям структуры Graph, полностью удалите typedef. Если вы хотите скрыть это от пользователя, используйте функции доступа к коду, например:
// cities.h
int getNodeCount(Graph g);
// cities.c
int getNodeCount(struct Graph * g) {
return g->nodeCount;
}
И используйте это так:
Graph g;
int nodeCount = getNodeCount(g);
Обратите внимание, что я НЕ использовал typedef в определении функции. Только в своем прототипе.
Спасибо за Ваш ответ. Поскольку я написал эту библиотеку для себя, я просто знаю, как это будет выглядеть, но спасибо за предложения.
typedef struct Graph * Graph;
это вводит в заблуждение, я рекомендую переименовать его во что-то более описательное, напримерGraphPtr
. Потому что люди смотрят наGraph x;
и думают, что в стеке естьGraph
, хотя на самом деле это просто указатель.