воскресенье, 4 июля 2010 г.

Шаблонная реализация перевода числа в строку

Шаблонная реализация функции перевода числа в строку.
Практического толку не очень много, зато разобрался в шаблонах получше.

Логарифм произвольного основания:



Сам перевод в строку:



Вам предлагается найти ошибки. Одна точно есть и допущена специально.

Вот исходный код: http://codepad.org/YeanrJjQ

UPD:
Чуток изменил код, ошибку исправил тоже.
Теперь используется статическая память, вместо динамической.



Теперь посмотри как Visual Studio 2008 разберётся с этим:



Вот что у нас получилось:



Видно как в статическую память записываются 3 цифры '7',
'3', '1' и производится вызов функции печати на консоль.

Код для Visual Studio тут - http://codepad.org/Z4rplbF7
Для других компиляторов следует закомментить лэйблы со смайлами)))

5 комментариев:

Pushkoff комментирует...

вот это:
static const int value
нужно заменить на
enum
{
value = ...
};

ну и судя по коду это далеко не компайл тайм... хотя очень хочется посмотреть на асм-листинг...

Pushkoff комментирует...

вроде компайл тайм

push 3
call ??2@YAPAXI@Z ; operator new
add esp, 4
mov DWORD PTR ?str@?1???$intToBase@$09$0IJ@@@YAPADXZ@4PADA, eax
mov DWORD PTR [eax], 3617585 ; 00373331H <=== вот число
; Line 58
xor eax, eax
; Line 59
ret 0

[k06a] комментирует...

Pushkoff, мне кажется в данном применении без разницы что использовать enum или static const int ...

Ошибка, о которой я говорил не относится даже к идее шаблонов. Она никогда и никак себя не проявит при выполнении (я думаю случай мало вероятен). Но тем не менее это ошибка.

Код был такой:
intToBase<10, 137>();

Pushkoff, в вашем листинге очень хорошо видно, что сперва выделяется память оператором new, а затем в эту память пишется константа 0x00373331. Эта константа ни что иное, как коды четырёх символов: '\0', '7', '3', '1'. И так как в x86 архитектуре младший байт имеет младший адрес, то это будет строка "137\0".

В ассемблерном листинге видно мою ошибку :)

P.S. Pushkoff, спасибо за листинг :)

Pushkoff комментирует...

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

[k06a] комментирует...

Pushkoff, ладно не буду испытывать судьбу (детали реализации компиляторов).
Быть enum-у))