LINUX.ORG.RU

Eclipse: проблема с #ifndef


0

2

Занялся программиованием arm-микроконтроллеров. Пришлось юзать пока глючный Eclipse, потихонечку разгребаю его ошибки. Вот уперся в одну, никак не поддается, хотя я сам могу тупить по неопытности.

Вот мой проект: https://github.com/dzusan/sensitizer/tree/master/sensitizer_probe

Кароче суть в том, что компилятор ругается на неоднократное объявление переменных, хотя я вроде все ifndef'ы грамотно расставил в хедерах.

./main.o: In function `main':
/home/dzusan/workspace/sensitizer_probe/Debug/../main.c:11: multiple definition of `rxCount'
./calculations.o:/home/dzusan/workspace/sensitizer_probe/Debug/../calculations.c:12: first defined here
./main.o:(.rodata+0x0): multiple definition of `START_RX_BYTE'
./calculations.o:(.rodata+0x0): first defined here
./main.o:(.rodata+0x4): multiple definition of `rxSeq'
./calculations.o:(.rodata+0x4): first defined here
./main.o: In function `main':
/home/dzusan/workspace/sensitizer_probe/Debug/../main.c:13: multiple definition of `txCount'
./calculations.o:/home/dzusan/workspace/sensitizer_probe/Debug/../calculations.c:12: first defined here
./main.o:(.rodata+0x44): multiple definition of `START_TX_BYTE'
./calculations.o:(.rodata+0x44): first defined here
./main.o:(.rodata+0x48): multiple definition of `txSeq'
./calculations.o:(.rodata+0x48): first defined here
collect2: error: ld returned 1 exit status
make: *** [sensitizer_probe.elf] Ошибка 1

Пришлось юзать пока глючный Eclipse, потихонечку разгребаю его ошибки

Забей на это говно. Используй vim, emacs или mc. Тогда, по крайней мере, ты будешь искать глюки у себя в голове, а не в инструментах.

tailgunner ★★★★★
()

смотри что передается компилятору в параметрах - если все как ты задал, то eclipse вообще не причем

wota ★★
()
Ответ на: комментарий от panter_dsd

Подозреваю, что gcc одинаковый запускается, что из-под креатора, что из-под эклипса, поэтому глупо надеяться, что при смене ИДЕ, изменятся ошибки.

EugeneBas ★★
()
Ответ на: комментарий от unsigned

Конечно это может быть и не эклипс, просто на него грешу из-за странных, вылезавших у меня ошибок и из-за нелестных репортов. Но если это не его косяк, сути дела это не меняет.

Dzusan
() автор топика
[andrew@andrew-desktop ~]$ gcc --help
Usage: gcc [options] file...
Options:
  -E                       Preprocess only; do not compile, assemble or link

Попробуй результат просмотреть

frozenix ★★★
()
Ответ на: комментарий от frozenix
Building file: ../main.c
Invoking: ARM Sourcery Linux GCC C Compiler
arm-none-eabi-gcc -E -DSTM32F10X_MD -DUSE_STDPERIPH_DRIVER -I"/home/dzusan/workspace/sensitizer_probe/CMSIS" -I"/home/dzusan/workspace/sensitizer_probe" -I"/home/dzusan/workspace/sensitizer_probe/STM32F10x_StdPeriph_Driver/inc" -O0 -Wall -Wa,-adhlns="main.o.lst" -c -fmessage-length=0 -MMD -MP -MF"main.d" -MT"main.d" -mcpu=cortex-m4 -mthumb -g3 -gdwarf-2 -o "main.o" "../main.c"
Finished building: ../main.c

То же самое и с остальными файлами. Никаких ошибок не происходит.

Dzusan
() автор топика
Ответ на: комментарий от frozenix

Jetty, ты все правильно заметил. Только вот конфилктовать они не должны ибо globals.h заключен в ifndef

Причем в обширных библиотеках, присутствующих в проекте, точно такая же конструкция спокойно компилится.

Dzusan
() автор топика
Ответ на: комментарий от Dzusan
// main.c
volatile int rxCount = 0;

// calculations.c
volatile int rxCount = 0;

rxCount включается дважды, в два разных *.c файла, это недопустимо в Си.

ifndef помогает избежать включения дважды, в пределах ОДНОГО *.c файла.

frozenix ★★★
()
Последнее исправление: frozenix (всего исправлений: 1)
Ответ на: комментарий от frozenix

Можно попробовать перенести все из globals.h в globals.c, а вместо него написать что-то вроде

//...
extern volatile int rxCount;
//...

frozenix ★★★
()
Последнее исправление: frozenix (всего исправлений: 1)

реквестирую

grep "GLOBALS_H_" stm32f10x.h
и в остальных хедерах цмсис или откуда он там.

aol ★★★★★
()
Ответ на: комментарий от Dzusan

Только вот конфилктовать они не должны ибо globals.h заключен в ifndef

Это значит лишь, что объявления классов или функций каких-нибудь не будут конфликтовать.

У функции есть определение, то бишь некоторый код. Когда компилируется отдельный файл *.c, создаётся объектный файл, где лежит в том числе и скомпилированный код функции. Когда компилируется несколько файлов, то хоть ifndef там, хоть что, будет несколько объектных файлов, и в каждом свой скомпилированный код функции. И при сборке объектных файлов в программу возникает ошибка.

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

// utils.h - объявления
#pragma once
extern int g_counter;
void updateCounterWithString(const char *string);

// utils.c - определения, в объектном файле utils.o будет код функции и место для переменной
#include "utils.h"
#include <string.h>

int g_counter = 0;
void updateCounterWithString(const char *string)
{
    g_counter += strlen(string);
}

// main.c - просто использует utils.h
#include "utils.h"
#include <stdio.h>

int main()
{
    // ...
    printf("Counter value: %d", g_counter);
    return 0;
}
quiet_readonly ★★★★
()
Ответ на: комментарий от quiet_readonly

quiet_readonly спасибо за подробный ответ!

Странно, сколько прогал не доводилось обращать внимания на сей важный факт...

А в *.с файле квалификаторы типа volatile, const писать уже не надо?

Dzusan
() автор топика
Ответ на: комментарий от Dzusan

Вопрос решил компилятор: сказал типа «где квалификаторы в определении?» Пришлось написать.

Dzusan
() автор топика
Ответ на: комментарий от Dzusan

Пременная должна _определяться_ (int var) в С файле, и объявляться в H-файле(хидере) (extern int var).
Все что я сказал справидливо в том случае если «позже» вси эти С файлы будут собраны в одну библиотеку/архив. Бест пректис так сказать :)

И ифндеф тебе не поможет. Потому что во время компиляции каждого С файла по отдельности для него и правда не определён твой хидер гуард.

Jetty ★★★★★
()
Ответ на: комментарий от rimsleur

Посмотрел - говно какое-то, они еще и бобла за него хотят :) Кейт почти тож самое :) Только легче и шустрее

Jetty ★★★★★
()
Ответ на: комментарий от Jetty

Можно и не платить. Хм, странно, я его и выбрал-то из-за нормальной скорости на нетбуке.

rimsleur
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.