Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Общие вопросы > Ошибка линковщика


Автор: PILOT 13.12.2004, 14:59
Не могу разобраться в одной ошибке.

Сама ошибка (предупреждение) выглядит так:
Цитата
Warning[w6]: Type conflict for external/entry "TTriStateReg::TTriStateReg()", in module init against external/entry in module rc; function return types
are different; class/struct/union field names do not match: r28 vs YL
Warning[w35]: There is more than one definition for the struct/union type with tag 'TTriStateReg'; class/struct/union field names do not match: YL vs r28

Не обращайте внимание на r28, это регистр, такой же как и A на PC.

Я изучаю Си (для контроллеров) но принцип везде один и тот же.
Сначала, когда я не знал правил Си, взял и описал классы включая функции класса в файле .h .
И все было без ошибок.
Затем я прочитал, что нужно разделять объявления и сами функции и появилось следующее:

Файл .h
Код

/* объявления */

enum   TGyst {neutral,minus,plus};// тип для хранения текущего положения рег-ра

class T_RC //класс rc-цепочки
{
public:
 float   iteration_step;
 float   tau_z;
 float   tau_r;
 float   ec;
 float   uc;            
 void    init(float t_z,float t_r,float ec0,float uc0,float i_s);
 void    do_iteration(char fzr);
};

class TTriStateReg // класс регулятор
{            
 private:                        
 TGyst   Gyst;
 public:        
  TTriStateReg(void);
 char    YL;
 char    YH;
 float   Razb;
 float   Mup;
 float   Mdown;
 float   Pup;
 float   Pdown;
 float   Ecmax;
 T_RC    rc;
 void    init(float t_z,float t_r,float ec0,float uc0,float i_s,float Mu,float Md,float Pu,float Pd, float Ecm,float Razb,TGyst G);
 void    analyze(void);
 void    do_rc_step(void);
};

class TPlavn
{          
 public:
  TPlavn(void);
 float   In;
 float   Out;
 float   KL;
 float   KH;    
 void    do_iteration(char Speed);
 void    SetParams(float K_0,float K_1);
};



И файл cpp:

Код

/* модуль */

#include "rc.h"

/*****************************************************************************
Функции класса T_RC
*****************************************************************************/
void T_RC::init(float t_z,float t_r,float ec0,float uc0,float i_s)
{
 tau_z=t_z;
 tau_r=t_r;
 ec=ec0;
 uc=uc0;
 iteration_step=i_s;
}

void T_RC::do_iteration(char fzr)
{
 if(!fzr)//если разряд
 {
   uc=uc+(iteration_step/tau_r)*(ec-uc);
 }
 else   //если заряд
 {
   uc=uc+(iteration_step/tau_z)*(ec-uc);
 }
}

/*****************************************************************************
Функции класса TTriStateReg
*****************************************************************************/
TTriStateReg::TTriStateReg(void)// конструктор
{
 YL=0;
 YH=0;
}

void TTriStateReg::init(float t_z,float t_r,float ec0,float uc0,float i_s,float Mu,float Md,float Pu,float Pd, float Ecm,float R,TGyst G)
{
 YL=0;
 YH=0;
 Razb=R;
 Gyst=G;
 rc.init(t_z,t_r,ec0,uc0,i_s);
 Mup=Mu;
 Mdown=Md;
 Pup=Pu;
 Pdown=Pd;
 Ecmax=Ecm;
}

void TTriStateReg::analyze(void)
{
 switch(Gyst)
 {
   case neutral:
     if((Razb-rc.uc)>Pup)
     {
       Gyst=plus;
       rc.ec=Ecmax;
       YH=1;
       YL=0;
     }
     else
     {
       if((Razb-rc.uc)<Mup)
       {
         Gyst=plus;
         rc.ec=-Ecmax;
         YH=0;
         YL=1;
       }
     }
   break;
   case plus:
     if((Razb-rc.uc)<Pdown)
     {
       Gyst=neutral;
       rc.ec=0;
       YH=0;
       YL=0;
     }
   break;
   case minus:
     if((Razb-rc.uc)>Mdown)
     {
       Gyst=neutral;
       rc.ec=0;
       YH=0;
       YL=0;
     }
   break;
 }
}
                         
void TTriStateReg::do_rc_step(void)
{
 rc.do_iteration((char)Gyst);
}

/*****************************************************************************
Функции класса TPlavn
*****************************************************************************/
TPlavn::TPlavn(void)
{
 KL=0;
 KH=0;
}

void TPlavn::do_iteration(char Speed)
{

float K;

 if(Speed)
 {
   K=KH;
 }
 else
 {
   K=KL;
 }
 if(In>Out)
 {
   Out+=K;
 }
 else
 {      
   Out-=K;
 }
}

void TPlavn::SetParams(float K_0,float K_1)
{
 KL=K_0;
 KH=K_1;
}


То что это предупреждение а не ошибка это хорошо, но все же разобраться считаю нужным.
Спасибо.

СУВ.

Автор: bel_nikita 13.12.2004, 15:23
Во-первых, нужно сделать типа того
rc.H
Код
#ifndef __MY_HEADER__
#define __MY_HEADER__

// ....
// твой код
// ....

#undef __MY_HEADER__


rc.c
Код

/* модуль */
#include "rc.h"
/*****************************************************************************
Функции класса T_RC
*****************************************************************************/

...

Во-вторых, если пишешь на Си, то причем тут cpp? smile
В-третьих, в Си нет классов, а есть только структуры smile
В четвертых, я так и не понял. Изучаешь С или С++? smile

Автор: srd 13.12.2004, 15:23
Warning w35 навёл на подозрения... Добавь во все заголовочные файлы стражи включения.
Например, для rc.h
Код

#ifndef __RC__
#define __RC__

// много кода

#endif


Автор: PILOT 13.12.2004, 15:43
Цитата(bel_nikita @ 13.12.2004, 12:23)
Во-вторых, если пишешь на Си, то причем тут cpp? smile
В-третьих, в Си нет классов, а есть только структуры smile
В четвертых, я так и не понял. Изучаешь С или С++? smile

smile
Ну, Си++ конечно.

За комментарии спасибо, сейчас попробую реализовать советы.

А вот по поводу w35, это значит что я мог где-то уже объявить класс?
И всед за этим: Если у меня более одного файла кторорые содержат: my.h, в котором описанное выше содержимое (Файл .h), это может вызвать подобную ошибку?
Я просто думал что .h можно сколько угодно и везде привинчивать... это так?

СУВ.

Автор: srd 13.12.2004, 15:53
Цитата
А вот по поводу w35, это значит что я мог где-то уже объявить класс?

Да. Например, если у тебя заголовочный файл включается больше одного раза в одном CPP-файле (напрямую, или через другие заголовки - неважно). Препроцессор просто убирает #include, а в её место вставляет содержимое заголовочного файла.

Цитата
И всед за этим: Если у меня более одного файла кторорые содержат: my.h, в котором описанное выше содержимое (Файл .h), это может вызвать подобную ошибку?

Да.

Цитата
Я просто думал что .h можно сколько угодно и везде привинчивать... это так?

В чистом виде нет. Но если в заголовках есть стражи включения, то можно писать #include много раз, включен он будет только один раз.

Автор: PILOT 13.12.2004, 16:04
Попробовал стража. Не помогает. smile Те же два предупреждения.

Обнаружил, что BreakPoint в теле конструктора TTriStateReg не работает (говорит, мол, некоторые точки останова не будут активны).


Автор: srd 13.12.2004, 16:12
А можешь показать содержимое второго CPP-файла? (который init.cpp). И как писал стражей включения? И сами H-файлы случайно не пытаешься скомпилировать?

Автор: PILOT 13.12.2004, 16:36
Так!
Нашел кое-что.

Увлекся Си++ и забыл, что YL зарезервированное слово.
Теперь все Ок!

СУВ.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)