Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1]   Вниз
  Печать  
Автор Тема: Макросы в C++  (Прочитано 6369 раз)
0 Пользователей и 1 Гость смотрят эту тему.
oktonion
Постоялец

ru
Offline Offline

« : 19-09-2014 10:57 » 

Доброго времени суток.

Код:

#define K1 42
#define CR(...) {__VA_ARGS__'\0'}
#define XOR(c) (c)^K1,

#define MCR4(s)   \
CR(                      \
XOR(*((#s) + 0))  \
XOR(*((#s) + 1))  \
XOR(*((#s) + 2))  \
XOR(*((#s) + 3))  \
)


Код:

char str[] = MCR4(TEST);


Приведенный выше макрос в моем представлении должен раскрыться в

Код:
{'T'^42, 'E'^42, 'S'^42, 'T'^42, '\0'}


и на этапе компиляции(?) сформировать в str строку "~oy~", ну или что то в этом духе.

Тем не менее после компиляции в Embarcadero C++ Builder XE5 просмотрев бинарник можно увидеть  в нем 4 строки TEST, разделенных пробелами.

Вопросы:
Что я делаю не так? (ну кроме того что макросы в ++ это зло и т.п.)
Как можно добиться с помощью препроцессора аналогичного преобразования строки? (подозреваю, что constexpr поможет, но его поддержки пока что нет нормальной нигде, ну может в GCC разве что)

PS:
Почему 4 строки то появляются в бинарнике?
« Последнее редактирование: 19-09-2014 11:02 от oktonion » Записан
RXL
Технический
Администратор

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #1 : 19-09-2014 11:50 » 

(подозреваю, что constexpr поможет, но его поддержки пока что нет нормальной нигде, ну может в GCC разве что)

В точку!

Почему 4 строки то появляются в бинарнике?

Наверно стоит заглянуть в доки целевого препроцессора и узнать, что и как они поддерживают. На худой конец сделать тоже самое рантайм.
Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.

"железокаменный метеорит" мог образоваться от расплавления металлических конструкций в результате например ядерного взрыва и стекания жидкого железа в какой нибудь щебень (c) Иванов С.
Джон
просто
Администратор

de
Online Online
Пол: Мужской

« Ответ #2 : 19-09-2014 12:58 » 

Макрос работает, по крайней мере в VS 2012


* ss1.jpg (53.21 Кб - загружено 471 раз.)
Записан

Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома.
"Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash
"Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman
"All science is either physics or stamp collecting." Ernest Rutherford
"Wer will, findet Wege, wer nicht will, findet Gründe."
oktonion
Постоялец

ru
Offline Offline

« Ответ #3 : 19-09-2014 13:08 » 

RXL,

Так на constexpr я понимаю как это можно легко и без фокусов сделать. Я понять не могу что не так в моей реализации через макросы.
Да и нет поддержки нормальной нового стандарта в RAD.

Джон,

Работать то он работает, да в рантайме. Основной вопрос в том - откуда в бинарнике берется строка TEST?
Идея то в чем:
если бы на этапе компиляции макрос раскрывался как надо, то в результате в бинарнике неоткуда взяться было этой строке, так как ее просто нет уже. Есть "отхоренная" поэлементно строка. Но тем не менее, хоть в str записывается верный результат, в бинарнике остается исходная строка да еще и в 4 экземплярах.

Я понимал бы такое поведение в результате "умной" оптимизации компилятором, хотя тоже тот еще трюк. Но сборку то провожу без оптимизаций, если верить в настройки в самом билдере.

Если сравнить результаты работы кода:
Код:
char str[] = MCR4(TEST);

и

Код:
char str[] = {'T'^42, 'E'^42, 'S'^42, 'T'^42, '\0'};

то в первом случае в бинарнике 4 строки TEST через пробелы, во втором случае - одна строка ~oy~.
« Последнее редактирование: 19-09-2014 13:50 от oktonion » Записан
Джон
просто
Администратор

de
Online Online
Пол: Мужской

« Ответ #4 : 19-09-2014 13:37 » 

А компилируется в Debug или Release?
Записан

Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома.
"Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash
"Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman
"All science is either physics or stamp collecting." Ernest Rutherford
"Wer will, findet Wege, wer nicht will, findet Gründe."
oktonion
Постоялец

ru
Offline Offline

« Ответ #5 : 19-09-2014 13:45 » 

Результат и в Debug и в Release одинаковый (TEST и там и там в 4х экземплярах с пробелами).  Меня одолевают смутные сомнения
У меня встудии нет под рукой, но что то мне кажется что там тоже в бинарнике будет присутствовать исходная строка.
Под компиляцией без оптимизации я подразумеваю Debug билд с отключенными оптимизациями и без CodeGuard.
« Последнее редактирование: 19-09-2014 13:51 от oktonion » Записан
Джон
просто
Администратор

de
Online Online
Пол: Мужской

« Ответ #6 : 19-09-2014 14:24 » 

VS 2013 Debug присутствует один раз (в 2012 Debug тоже только один раз), в Release нет ни одного.

Код: (C++)

#include "stdafx.h"

#define K1 42
#define CR(...) {__VA_ARGS__'\0'}
#define XOR(c) (c)^K1,

#define MCR4(s)   \
        CR(                      \
        XOR(*((#s) + 0))  \
        XOR(*((#s) + 1))  \
        XOR(*((#s) + 2))  \
        XOR(*((#s) + 3))  \
        )



int _tmain(int argc, _TCHAR* argv[])
{
        char str[] = MCR4(PRIVETSPORTSMENAM);

        return 0;
}

Настройки проекта по умолчанию, изменил только Runtime Library на Multi-threaded Debug (/MTd), вместо DLL в обоих случаях (Debug/Release)

* MacroTest.rar (31.18 Кб - загружено 126 раз.)
* MacroTest_Debug.rar (124.41 Кб - загружено 124 раз.)
« Последнее редактирование: 19-09-2014 15:03 от Джон » Записан

Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома.
"Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash
"Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman
"All science is either physics or stamp collecting." Ernest Rutherford
"Wer will, findet Wege, wer nicht will, findet Gründe."
oktonion
Постоялец

ru
Offline Offline

« Ответ #7 : 19-09-2014 14:36 » 

Джон ,

Интересно... а в результате в бинарнике zxc|? Или zxc|\0ETSPORTSMENAM?
Выходит что это у эмбаркадеры такой препроцессор кривой? Жаль
Записан
Джон
просто
Администратор

de
Online Online
Пол: Мужской

« Ответ #8 : 19-09-2014 15:01 » 

Вот так


зы Бинарники я прицепил к перед. посту, можешь сам "поковыряться".

* ss1.gif (6.34 Кб - загружено 410 раз.)
Записан

Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома.
"Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash
"Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman
"All science is either physics or stamp collecting." Ernest Rutherford
"Wer will, findet Wege, wer nicht will, findet Gründe."
oktonion
Постоялец

ru
Offline Offline

« Ответ #9 : 19-09-2014 15:20 » 

Джон ,

спасибо, посмотрел бинарники. В дебажном строка есть, тем не менее в релизном нет ни строки исходной, ни "отхоренной".
Там же от
Код:
P(0x52), R(0x55), I(0x49), V(0x56)

должно получиться
Код:
z(0x7A), x(0x78), c(0x63), |(0x7C)
.
Но такой строки в бинарнике нет. Видимо у вас значение str никак не используется и компилятор его заоптимизировал просто выкинув. А черт его знает...

PS: Как тут мелко аттачи отображаются - еле разглядел. -_-
« Последнее редактирование: 19-09-2014 16:59 от oktonion » Записан
Джон
просто
Администратор

de
Online Online
Пол: Мужской

« Ответ #10 : 29-09-2014 11:13 » 

Сорри, просто 19-го это были последние секунды перед отпуском...

Так чем дело закончилось? Или НЕ закончилось?
Записан

Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома.
"Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash
"Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman
"All science is either physics or stamp collecting." Ernest Rutherford
"Wer will, findet Wege, wer nicht will, findet Gründe."
oktonion
Постоялец

ru
Offline Offline

« Ответ #11 : 06-10-2014 18:31 » 

Необычный способ провести последние секунды перед отпуском. Улыбаюсь В любом случае спасибо за помощь.

Пока что все закончилось на том, что под студией 10, 13 макрос раскрывается как я и предполагал - то есть ожидаемо "отхоренная" строка поэлементно.
Под GCC все прекрасно решается средствами нового стандарта, что тоже радует.
А вот под нужным RAD билдером c++ почему так раскрывается макрос странно? Я не нашел ответа. Слабо понимаю как его так можно раскрыть чтобы получить 4 строки исходных. А черт его знает...
Записан
Страниц: [1]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines