|
|
  |
WinAVR, G++, template, linking, Помогите найти ошибку при применении template. |
|
|
|
Jun 9 2006, 06:10
|
Участник

Группа: Новичок
Сообщений: 34
Регистрация: 2-10-05
Пользователь №: 9 141

|
Не понимаю. Где может быть ошибка при использовании template? Без использования template проект собирается нормально. Проект состоит из 3 фалов main.cpp - откуда вызываю функцию Func, clMy.h - где объявляю класс clMy, и clMy.cpp - где описана реализация функции Func. Вот как это выглядит: main.cpp Код #include <avr/io.h> #include "clMy.h"
int main(void) { clMy My; volatile uint8_t d=My.Func(3); for(;;); return (0); }; clMy.h Код #include <avr/io.h> #ifndef _clMy_ #define _clMy_
class clMy { private: uint8_t massiv[count]; public: uint8_t Func(uint8_t); };
#endif clMy.cpp Код #include "clMy.h"
uint8_t clMy::Func(uint8_t temp) { return(massiv[temp]); } Это все собирается правильно. Но как только хочу использовать template проект собираться перестает. Линковщик ругается, что не определена ссылка на Func. Видимо что-то неправильно делаю, но что? С плюсами еще только знакомлюсь. Помогите. main.cpp Код #include <avr/io.h> #include "clMy.h"
int main(void) { clMy<4> My; volatile uint8_t d=My.Func(3); for(;;); return (0); }; clMy.h Код #include <avr/io.h> #ifndef _clMy_ #define _clMy_
template <uint8_t count>class clMy { private: uint8_t massiv[count]; public: uint8_t Func(uint8_t); };
#endif clMy.cpp Код #include "clMy.h"
template <uint8_t count>uint8_t clMy<count>::Func(uint8_t temp) { return(massiv[temp]); }
|
|
|
|
|
Jun 9 2006, 06:52
|

Профессионал
    
Группа: Свой
Сообщений: 1 065
Регистрация: 8-10-05
Из: Kiev, UA
Пользователь №: 9 380

|
Насколько я помню шаблоны, в объявлении, в <> указыватся некий абстракный тип T, Код template <T> class Storage{ T array[5]; } а в тексте этот тип подменяется на один из существующих типов, и соответсвеено генерится код с использованием этого типа: Код { ... Storage<int> intStorage Storage<myClass> classStorage; ... } таким образом создаются массивы из разных типов данных. Тут как я вижу clMy<4> My; Для какого типа создается объект? И если известного, тогда зачем шаблон? Цель шаблона использовать одинаковый алгоритм для разных типов данных, будет создано столько функций сколько типов будет заданно в качестве параметра. В данном случае код для функции просто не генерится. Извините, если что-то не понял в коде и неправильно истолковал.
--------------------
Вони шукають те, чого нема, Щоб довести, що його не існує.
|
|
|
|
|
Jun 9 2006, 07:37
|
Участник

Группа: Новичок
Сообщений: 34
Регистрация: 2-10-05
Пользователь №: 9 141

|
Спасибо за ответ. Дело в том, что я только осваиваю плюсы и поэтому еще не знаю всех возможностей. В данном случае я хотел задавать размер массива, тип массива всегда одинаков. Размер массива будет использоваться неоднократно в функциях этого класса, поэтому хотелось автоматизации. Можно конечно реализовать это с помощью define, но с template разобраться хотелось бы в любом случае. По-поводу задания интегральных значений с помощью template читал у Страутрупа. Переписал класс с template задающим тип. Ошибка такая же. Значит что-то делаю не так  Код ----- main.cpp
#include <avr/io.h> #include "clMy.h"
int main(void) { clMy<uint8_t> My; volatile uint8_t d=My.Func(3); for(;;); return (0); }; ----- clMy.h
#include <avr/io.h> #ifndef _clMy_ #define _clMy_
template <class T>class clMy { private: T massiv[4]; public: T Func(uint8_t); }; #endif ----- clMy.cpp
#include "clMy.h"
template <class T> T clMy<T>::Func(uint8_t temp) { return(massiv[temp]); } Не собирается, так как опять не определить ссылки: Код Compiling: main.cpp avr-g++ -c -mmcu=at90can128 -I. -gdwarf-2 -DF_CPU=14745600UL -Os -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -Wall -Wa,-adhlns=main.lst -Ic:\Sourse\Library -std=gnu++98 -MD -MP -MF .dep/main.o.d main.cpp -o main.o main.cpp: In function `int main()': main.cpp:8: warning: unused variable 'd'
Compiling: clMy.cpp avr-g++ -c -mmcu=at90can128 -I. -gdwarf-2 -DF_CPU=14745600UL -Os -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -Wall -Wa,-adhlns=clMy.lst -Ic:\Sourse\Library -std=gnu++98 -MD -MP -MF .dep/clMy.o.d clMy.cpp -o clMy.o
Linking: main.elf avr-g++ -mmcu=at90can128 -I. -gdwarf-2 -DF_CPU=14745600UL -Os -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -Wall -Wa,-adhlns=main.o -Ic:\Sourse\Library -std=gnu++98 -MD -MP -MF .dep/main.elf.d main.o clMy.o --output main.elf -Wl,-Map=main.map,--cref -lm main.o: In function `main': c:\sourse\otl/main.cpp:8: undefined reference to `clMy<unsigned char>::Func(unsigned char)' C:\WinAVR\utils\bin\make.exe: *** [main.elf] Error 1 Может дело в makefile? Вот кусочки makefile: Код FORMAT = ihex TARGET = main CPPSRC = $(TARGET).cpp clMy.cpp CPPSTANDARD = -std=gnu++98 CPPFLAGS = -g$(DEBUG) CPPFLAGS += $(CDEFS) $(CINCS) CPPFLAGS += -O$(OPT) CPPFLAGS += -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums CPPFLAGS += -Wall CPPFLAGS += -Wa,-adhlns=$(<:.cpp=.lst) CPPFLAGS += $(patsubst %,-I%,$(EXTRAINCDIRS)) CPPFLAGS += $(CPPSTANDARD) LDFLAGS = -Wl,-Map=$(TARGET).map,--cref LDFLAGS += $(EXTMEMOPTS) LDFLAGS += $(PRINTF_LIB) $(SCANF_LIB) $(MATH_LIB) CPP = avr-g++ OBJCOPY = avr-objcopy OBJDUMP = avr-objdump OBJ = $(SRC:.c=.o) $(CPPSRC:.cpp=.o) $(ASRC:.S=.o) LST = $(SRC:.c=.lst) $(CPPSRC:.cpp=.lst) $(ASRC:.S=.lst) GENDEPFLAGS = -MD -MP -MF .dep/$(@F).d ALL_CPPFLAGS = -mmcu=$(MCU) -I. $(CPPFLAGS) $(GENDEPFLAGS)
all: begin gccversion sizebefore build sizeafter end
build: elf hex eep lss sym elf: $(TARGET).elf hex: $(TARGET).hex eep: $(TARGET).eep lss: $(TARGET).lss sym: $(TARGET).sym
SECONDARY : $(TARGET).elf .PRECIOUS : $(OBJ) %.elf: $(OBJ) @echo @echo $(MSG_LINKING) $@ $(CPP) $(ALL_CPPFLAGS) $^ --output $@ $(LDFLAGS)
%.o : %.cpp @echo @echo $(MSG_COMPILING) $< $(CPP) -c $(ALL_CPPFLAGS) $< -o $@ %.s : %.cpp $(CPP) -S $(ALL_CPPFLAGS) $< -o $@ %.i : %.cpp $(CPP) -E -mmcu=$(MCU) -I. $(CPPFLAGS) $< -o $@
|
|
|
|
|
Jun 9 2006, 10:24
|

Профессионал
    
Группа: Свой
Сообщений: 1 065
Регистрация: 8-10-05
Из: Kiev, UA
Пользователь №: 9 380

|
Скомпилировал в таком виде: Код template <class T>class clMy { private: T massiv[4]; public: T Func(int); };
template <class T> T clMy<T>::Func(int temp) { return(massiv[temp]); }
int main(void) { clMy<int> My; volatile int d=My.Func(3); for(;;); return (0); }; листинг: Код main.elf: file format elf32-avr
Sections: Idx Name Size VMA LMA File off Algn 0 .data 00000000 00800100 0000008e 00000122 2**0 CONTENTS, ALLOC, LOAD, DATA 1 .text 0000008e 00000000 00000000 00000094 2**0 CONTENTS, ALLOC, LOAD, READONLY, CODE 2 .bss 00000000 00800100 0000008e 00000122 2**0 ALLOC 3 .noinit 00000000 00800100 00800100 00000122 2**0 CONTENTS 4 .eeprom 00000000 00810000 00810000 00000122 2**0 CONTENTS 5 .stab 000001ec 00000000 00000000 00000124 2**2 CONTENTS, READONLY, DEBUGGING 6 .stabstr 000003fa 00000000 00000000 00000310 2**0 CONTENTS, READONLY, DEBUGGING Disassembly of section .text:
00000000 <__vectors>: 0: 19 c0 rjmp .+50 ; 0x34 2: 32 c0 rjmp .+100 ; 0x68 4: 31 c0 rjmp .+98 ; 0x68 6: 30 c0 rjmp .+96 ; 0x68 8: 2f c0 rjmp .+94 ; 0x68 a: 2e c0 rjmp .+92 ; 0x68 c: 2d c0 rjmp .+90 ; 0x68 e: 2c c0 rjmp .+88 ; 0x68 10: 2b c0 rjmp .+86 ; 0x68 12: 2a c0 rjmp .+84 ; 0x68 14: 29 c0 rjmp .+82 ; 0x68 16: 28 c0 rjmp .+80 ; 0x68 18: 27 c0 rjmp .+78 ; 0x68 1a: 26 c0 rjmp .+76 ; 0x68 1c: 25 c0 rjmp .+74 ; 0x68 1e: 24 c0 rjmp .+72 ; 0x68 20: 23 c0 rjmp .+70 ; 0x68 22: 22 c0 rjmp .+68 ; 0x68 24: 21 c0 rjmp .+66 ; 0x68 26: 20 c0 rjmp .+64 ; 0x68 28: 1f c0 rjmp .+62 ; 0x68 2a: 1e c0 rjmp .+60 ; 0x68 2c: 1d c0 rjmp .+58 ; 0x68 2e: 1c c0 rjmp .+56 ; 0x68 30: 1b c0 rjmp .+54 ; 0x68 32: 1a c0 rjmp .+52 ; 0x68
00000034 <__ctors_end>: 34: 11 24 eor r1, r1 36: 1f be out 0x3f, r1; 63 38: cf ef ldi r28, 0xFF; 255 3a: d4 e0 ldi r29, 0x04; 4 3c: de bf out 0x3e, r29; 62 3e: cd bf out 0x3d, r28; 61
00000040 <__do_copy_data>: 40: 11 e0 ldi r17, 0x01; 1 42: a0 e0 ldi r26, 0x00; 0 44: b1 e0 ldi r27, 0x01; 1 46: ee e8 ldi r30, 0x8E; 142 48: f0 e0 ldi r31, 0x00; 0 4a: 02 c0 rjmp .+4 ; 0x50
0000004c <.do_copy_data_loop>: 4c: 05 90 lpm r0, Z+ 4e: 0d 92 st X+, r0
00000050 <.do_copy_data_start>: 50: a0 30 cpi r26, 0x00; 0 52: b1 07 cpc r27, r17 54: d9 f7 brne .-10 ; 0x4c
00000056 <__do_clear_bss>: 56: 11 e0 ldi r17, 0x01; 1 58: a0 e0 ldi r26, 0x00; 0 5a: b1 e0 ldi r27, 0x01; 1 5c: 01 c0 rjmp .+2 ; 0x60
0000005e <.do_clear_bss_loop>: 5e: 1d 92 st X+, r1
00000060 <.do_clear_bss_start>: 60: a0 30 cpi r26, 0x00; 0 62: b1 07 cpc r27, r17 64: e1 f7 brne .-8 ; 0x5e 66: 09 c0 rjmp .+18 ; 0x7a
00000068 <__bad_interrupt>: 68: cb cf rjmp .-106 ; 0x0
0000006a <_ZN4clMyIiE4FuncEi>: 7 __zero_reg__ = 1 8 .global __do_copy_data 9 .global __do_clear_bss 11 .text 12 .Ltext0: 6a: fb 01 movw r30, r22 42 .weak _ZN4clMyIiE4FuncEi 6c: e6 0f add r30, r22 6e: f7 1f adc r31, r23 70: e8 0f add r30, r24 72: f9 1f adc r31, r25 74: 80 81 ld r24, Z 76: 91 81 ldd r25, Z+1; 0x01 78: 08 95 ret
0000007a <main>: 44 _ZN4clMyIiE4FuncEi: 1:main.cpp **** ... 46 .LM1: 47 /* prologue: frame size=0 */ 7a: c7 ef ldi r28, 0xF7; 247 7c: d4 e0 ldi r29, 0x04; 4 7e: de bf out 0x3e, r29; 62 80: cd bf out 0x3d, r28; 61 48 /* prologue end (size=0) */ 49 0000 FB01 movw r30,r22 50 .LBB2: 82: 63 e0 ldi r22, 0x03; 3 84: 70 e0 ldi r23, 0x00; 0 86: ce 01 movw r24, r28 88: 01 96 adiw r24, 0x01; 1 8a: ef df rcall .-34 ; 0x6a 52 .LM2: 8c: ff cf rjmp .-2 ; 0x8c Разбирайтесь
--------------------
Вони шукають те, чого нема, Щоб довести, що його не існує.
|
|
|
|
|
Jun 9 2006, 11:45
|
Участник

Группа: Новичок
Сообщений: 34
Регистрация: 2-10-05
Пользователь №: 9 141

|
ОК. Спасибо. У меня не собралось. Глянул в gcc.pdf, там описываются проблемы с использованием template, и как раз проблемы с линковкой. Спрошу в фидо. Будет ответ сообщу. Спасибо за помощь.
|
|
|
|
|
Jun 9 2006, 11:47
|
Участник

Группа: Новичок
Сообщений: 34
Регистрация: 2-10-05
Пользователь №: 9 141

|
ОК. Спасибо. У меня не собралось. Глянул в gcc.pdf, там описываются проблемы с использованием template, и как раз проблемы с линковкой. Спрошу в фидо. Будет ответ сообщу. Спасибо за помощь.
ОК. Спасибо. У меня не собралось. Глянул в gcc.pdf, там описываются проблемы с использованием template, и как раз проблемы с линковкой. Спрошу в фидо. Будет ответ сообщу. Спасибо за помощь.
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|