Модераторы: Daevaorn
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Коварство препроцессора ANSI C++ (оператор ##), или как склеивать символы со скобками 
:(
    Опции темы
Абабо
Дата 5.2.2008, 23:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 158
Регистрация: 14.1.2005

Репутация: нет
Всего: 1



У меня к вам немного странный вопрос.  Он возник у меня при попытке упрощения написания классов под Symbian. Суть вопроса следующая. Мне нужно написать макрос, заменяющий стандартные для Symbian-классов функции.  Вот одна из них:
Код

static Class *NewLC(Формальные параметры) 
{
Class* self = new (ELeave) Class;
    CleanupStack::PushL(self);
    self->ConstructClassL(Фактические параметры);
    return self; 
}

При написании макроса возникает проблема с передачей параметров – макрос должен получать два списка параметров (переменной длины) – формальные и фактические (например, (int a, float b) и (a,b)) и вставлять их в соотв. местах. Если бы я мог средствами препроцессора получить из формальных параметров фактические (например, (int a, float b) -> (a,b)), то проблемы бы не стояло – я бы передавал макросу переменный список формальных параметров (используя оператор …). Однако, как мне кажется, это за гранями возможности препроцессора, т.е. мне придётся вручную передавать фактические параметры. Но как тогда быть с отделением формальных параметров от фактических? Если заключать каждый список в скобки, то можно решить поставленную задачу. Так она решалась при использовании компилятора VC++:
Код

#define COMMON_NEWLC(Class, FormalArgs, ActualArgs) \    
    public: static Class *NewLC ## FormalArgs { \
        Class* self = CREATE(Class); \
        CleanupStack::PushL(self); \
        self->Construct ## Class ## L ## ActualArgs; \
        return self; }
class MyClass
{
    COMMON_NEWLC(MyClass, (int a, float b), (a,b))
…
};

Однако в моей задаче целевым компилятором является GCC, который пресекает подобную практику сообщениями ошибки: “ pasting "NewLC" and "(" does not give a valid preprocessing token”. 

Жду вашего совета. Спасибо.


Это сообщение отредактировал(а) Абабо - 5.2.2008, 23:23
--------------------
С уважением, Абабо.
PM MAIL   Вверх
SABROG
Дата 5.2.2008, 23:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Hacker
****


Профиль
Группа: Завсегдатай
Сообщений: 2481
Регистрация: 18.9.2006

Репутация: 4
Всего: 91



Сорри за оффтопик, а кто-то считает C++ кроссплатформенным... MSVC, GCC, BCC - у каждого свой стандарт, точно также как у MSSQL, MySQL, PosgreSQL, Oracle, SQLITE, FireBird...  smile 


--------------------
Национальная группа Russian Federation на QtCentre.
PM MAIL   Вверх
JackYF
Дата 5.2.2008, 23:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


полуавантюрист
****


Профиль
Группа: Участник
Сообщений: 5814
Регистрация: 28.8.2004
Где: страна тысячи озё р

Репутация: 18
Всего: 162



Цитата(Абабо @  5.2.2008,  22:10 Найти цитируемый пост)
public: static Class *NewLC ## FormalArgs { \

попробуй заменить на
Код

public: static Class *NewLC (## FormalArgs) { \



--------------------
Пожаловаться на меня как модератора можно здесь.
PM MAIL Jabber   Вверх
MAKCim
Дата 6.2.2008, 00:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Воін дZэна
****


Профиль
Группа: Экс. модератор
Сообщений: 5644
Регистрация: 10.12.2005
Где: Менск, РБ

Репутация: 52
Всего: 207



JackYF, 
и что?
в данном контексте скобки использовались для группировки множества параметров
в GCC такое недопустимо

Добавлено через 1 минуту и 15 секунд
твой способ
не позволит отличить формальные и фактические параметры


--------------------
Ах, у елі, ах, у ёлкі, ах, у елі злыя волкі ©

PM MAIL   Вверх
JackYF
Дата 6.2.2008, 01:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


полуавантюрист
****


Профиль
Группа: Участник
Сообщений: 5814
Регистрация: 28.8.2004
Где: страна тысячи озё р

Репутация: 18
Всего: 162



Цитата(MAKCim @  5.2.2008,  23:07 Найти цитируемый пост)
в данном контексте скобки использовались для группировки множества параметров
в GCC такое недопустимо

значит, не туда глянул :(

Цитата(SABROG @  5.2.2008,  22:52 Найти цитируемый пост)
а кто-то считает C++ кроссплатформенным...

Я. Вышеприведенная ситуация - досадна, но я считаю, что система Symbian для разработчика [censored33! Пожалуйста, соблюдайте элементарные правила приличия при общении на форуме], если она заставляет его писать макросы, а не классы-наследники или ещё какую штатную фиговину.



--------------------
Пожаловаться на меня как модератора можно здесь.
PM MAIL Jabber   Вверх
Mayk
Дата 6.2.2008, 09:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


^аВаТаР^ сообщение>>
****


Профиль
Группа: Участник
Сообщений: 2616
Регистрация: 22.5.2005
Где: за границей разум а

Репутация: 45
Всего: 134



я одного не понял --- а смысл так делать?
Цитата(Абабо @  6.2.2008,  03:10 Найти цитируемый пост)
#define COMMON_NEWLC(Class, FormalArgs, ActualArgs) \    
    public: static Class *NewLC ## FormalArgs { \
        Class* self = CREATE(Class); \
        CleanupStack::PushL(self); \
        self->Construct ## Class ## L ## ActualArgs; \
        return self; }

Код

//a.cpp. пара ## выкинута нафик
#define COMMON_NEWLC(Class, FormalArgs, ActualArgs) \    
    public: static Class *NewLC  FormalArgs { \
        Class* self = CREATE(Class); \
        CleanupStack::PushL(self); \
        self->Construct ## Class ## L  ActualArgs; \
        return self; }
class MyClass
{
    COMMON_NEWLC(MyClass, (int a, float b), (a,b))
:
};



Цитата(cpp a.cpp)

    public: static MyClass *NewLC (int a, float b) { MyClass* self = CREATE(MyClass); CleanupStack::PushL(self); self->ConstructMyClassL (a,b); return self; }


Добавлено @ 09:38
Цитата(SABROG @  6.2.2008,  03:52 Найти цитируемый пост)
Сорри за оффтопик, а кто-то считает C++ кроссплатформенным...

расскажи об этом trolltech'ам. а то ребята бедные не в теме.

Это сообщение отредактировал(а) Mayk - 6.2.2008, 09:39


--------------------
 Здесь был кролик. Но его убили.
Человеки < кроликов, йа считаю.
PM MAIL WWW ICQ   Вверх
Абабо
Дата 6.2.2008, 10:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 158
Регистрация: 14.1.2005

Репутация: нет
Всего: 1



Ну конечно же! Скобки же не должны обязательно прилегать к имени функции - во истину, всё простое гениально... А то я уже стал изощраться с конструкциями типа COMMON_NEWLC(MyClass,SEP(int a, float b),SEP(a,b)), потом же оказалось что мой VC++ 2003 (который я использую для отладки на эмуляторе) не поддерживает макросы с переменным числом параметров... 

Спасибо всем, а Mayk - особенно!
--------------------
С уважением, Абабо.
PM MAIL   Вверх
SABROG
Дата 6.2.2008, 11:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Hacker
****


Профиль
Группа: Завсегдатай
Сообщений: 2481
Регистрация: 18.9.2006

Репутация: 4
Всего: 91



Цитата(Mayk @ 6.2.2008,  09:36)
расскажи об этом trolltech'ам. а то ребята бедные не в теме.

Я не о том, что невозможно сделать кроссплатформенный проект. А о разности исполнения стандарта. Посмотри хотябы на спецификацию шаблонов, MSVC позволяют ее производить внутри класса, а GCC нет. В итоге C++ код, который должен быть кроссплатформенным вынужден использовать препроцессорные средства, чтобы проверить под каким из компиляторов производится сборка. А из-за разности алгоритма оптимизации создаются объектные файлы, которые могут не собираться с ошибками о всяких unresolved external, а на MSVC все ок. Еще есть косяки с пропиской области видимости объекта, там где MSVC схватает - GCC подавится. Еще в GCC есть тип long long , разные версии msvc его понимают по-разному. Или вот препроцессорная команда #pragma вообще для каждого компилятора разная, а MSVCшники упорно вставляют туда какое-нибудь подключение .lib файла и считают это нормальным. На самом деле подводных камней очень много.

Поэтому, если даже библиотека Qt сама кроссплатформенная, то вот приложения написанные с использованием Qt кроссплатформенными могут и не быть, даже если не используют системные API или сторонние библиотеки, которые были написанды для винды. Достаточно писать исходник только под msvc. Т.ч. для программиста желающиего писать кроссплатформенный софт правильно было бы выбрать mingw, если он пишет под виндой.

Это сообщение отредактировал(а) SABROG - 6.2.2008, 11:30


--------------------
Национальная группа Russian Federation на QtCentre.
PM MAIL   Вверх
JackYF
Дата 6.2.2008, 11:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


полуавантюрист
****


Профиль
Группа: Участник
Сообщений: 5814
Регистрация: 28.8.2004
Где: страна тысячи озё р

Репутация: 18
Всего: 162



Цитата(SABROG @  6.2.2008,  10:24 Найти цитируемый пост)
А о разности исполнения стандарта.

Ну да, она есть. Была и будет. И дальше что? smile


--------------------
Пожаловаться на меня как модератора можно здесь.
PM MAIL Jabber   Вверх
Mayk
Дата 6.2.2008, 12:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


^аВаТаР^ сообщение>>
****


Профиль
Группа: Участник
Сообщений: 2616
Регистрация: 22.5.2005
Где: за границей разум а

Репутация: 45
Всего: 134



Цитата(SABROG @  6.2.2008,  15:24 Найти цитируемый пост)
. А из-за разности алгоритма оптимизации создаются объектные файлы, которые могут не собираться с ошибками о всяких unresolved external, а на MSVC все ок.

С каких пор оптимизатор влияет на mangling?  smile 

Цитата(SABROG @  6.2.2008,  15:24 Найти цитируемый пост)
Еще в GCC есть тип long long , разные версии msvc его понимают по-разному. 

С какой версии MSVC понимает long long как тип, а не как синатксическую ошибку? smile 

Цитата(SABROG @  6.2.2008,  15:24 Найти цитируемый пост)
итоге C++ код, который должен быть кроссплатформенным вынужден использовать препроцессорные средства, чтобы проверить под каким из компиляторов производится сборка.

Всегда?

Цитата(SABROG @  6.2.2008,  15:24 Найти цитируемый пост)
Еще есть косяки с пропиской области видимости объекта, там где MSVC схватает - GCC подавится. 

Что такое прописка области видимости?  smile 

Цитата(SABROG @  6.2.2008,  15:24 Найти цитируемый пост)

Поэтому, если даже библиотека Qt сама кроссплатформенная, то вот приложения написанные с использованием Qt кроссплатформенными могут и не быть, даже если не используют системные API или сторонние библиотеки, которые были написанды для винды

Могут и не быть. А могут и быть. So what?

Цитата(SABROG @  6.2.2008,  15:24 Найти цитируемый пост)
Достаточно писать исходник только под msvc. Т.ч. для программиста желающиего писать кроссплатформенный софт правильно было бы выбрать mingw, если он пишет под виндой.

Этот фрагмент я не понял. 


--------------------
 Здесь был кролик. Но его убили.
Человеки < кроликов, йа считаю.
PM MAIL WWW ICQ   Вверх
SABROG
Дата 6.2.2008, 13:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Hacker
****


Профиль
Группа: Завсегдатай
Сообщений: 2481
Регистрация: 18.9.2006

Репутация: 4
Всего: 91



Если чесно, не хочеться углубляться в тему переносимости, тем более что это оффтопик.
Просто недавно пытался добавить возможность сборки одного проекта с помощью mingw, так он собирается msvc. Пришлось исправлять исходники в некоторых местах, столкнулся как-раз с теми проблемами, что описал выше. Unresolved External побороть мне так и не удалось, т.к. для этого надо проследить всю цепочку наследования класса, для меня это оказалось слишком сложно, т.к. вся цепочка достаточно большАя часть проекта, а сэмулировать проблему на мелкой программе не удалось. Mangling даже не при чем, т.к. в проекте не линковались библиотеки собранные на других компиляторах. Просто тесты показали, что в зависимости от уровня оптимизации методы и данные могут либо экспортироваться, либо не экспортироваться, т.к. если переменная или метод не используется они "киляются"...

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

Это сообщение отредактировал(а) SABROG - 6.2.2008, 13:43


--------------------
Национальная группа Russian Federation на QtCentre.
PM MAIL   Вверх
tsrtg
Дата 12.2.2008, 01:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 2
Регистрация: 12.2.2008

Репутация: нет
Всего: нет



Цитата

С какой версии MSVC понимает long long как тип, а не как синатксическую ошибку?


Все три установленные у меня версии MSVC (7.1, 8.0 и 9.0) понимают long long именно как 64-битный целочисленный тип.
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

Добро пожаловать!

  • Черновик стандарта C++ (за октябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика(4.4мб).
  • Черновик стандарта C (за сентябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика (3.4мб).
  • Прежде чем задать вопрос, прочтите это и/или это!
  • Здесь хранится весь мировой запас ссылок на документы, связанные с C++ :)
  • Не брезгуйте пользоваться тегами [code=cpp][/code].
  • Пожалуйста, не просите написать за вас программы в этом разделе - для этого существует "Центр Помощи".
  • C++ FAQ

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0843 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.