C — переопределение Typedef с разными типами

Возьмем пример моего проекта:

У меня есть 2 файла, file1.c и file2.c. Оба этих файла имеют заголовочный файл (file1.h и file2.h). У меня также есть файл struct.h, который содержит:

typedef struct {
    char region[80];
    int startDate;
    int endDate;
    int startTime;
    int endTime;
} Schedule;

Оба заголовочных файла (file1.h и file2.h) включают struct.h, а main.c включает и file1.h, и file2.h. Допустим, это main.c:

#include <stdio.h>
#include "file1.h"
#include "file2.h"

int main() {
    /* function from file1.h */
    int num1 = sum(1, 3);

    /* function from file2.h */
    int num2 = mul(4, 5);
}

Теперь в main.c я получаю сообщение об ошибке: In included file: typedef redefinition with different types. Я предполагаю, что ошибка связана с тем, что и file1.h, и file2.h объявляют свои собственные общие структуры из struct.h.

Есть идеи по решению проблемы?

Использование включает охрану. Это стандартный подход к предотвращению множественных проблем с включением. Глядя, если я могу найти дубликат. Если нет, ваша тестовая книга обязательно должна их обсудить.

Avi Berger 22.01.2023 07:35
Этот пост может помочь
Avi Berger 22.01.2023 07:40
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
2
63
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Это очень распространенная проблема при включении других файловых юнитов, и решение состоит в том, чтобы всегда использовать включенные защитные элементы в вашем заголовочном файле, например.

// struct.h
#ifndef INCLUDED_STRUCT_H
#define INCLUDED_STRUCT_H

typedef struct {
  char region[80];
  int startDate;
  int endDate;
  int startTime;
  int endTime;
} Schedule;

#endif

С этим include guard в вашем main.c, даже если он включает в себя и file1.h, и file2.h, есть только определение struct.

Ответ принят как подходящий

Стандартный способ решить эту проблему — заключить определения в struct.h внутри директивы препроцессора #if или #ifdef, чтобы избежать дублирования определений, если файл включается более одного раза. Это обычно называют включенными охранниками.

структура.ч:

#ifndef STRUCT_H_INCLUDED
#define STRUCT_H_INCLUDED

typedef struct {
    char region[80];
    int startDate;
    int endDate;
    int startTime;
    int endTime;
} Schedule;

#endif /* STRUCT_H_INCLUDED */

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

Другие вопросы по теме