| Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
| Форум программистов > C/C++: Общие вопросы > Коварство препроцессора ANSI C++ (оператор ##) |
| Автор: Абабо 5.2.2008, 23:10 | ||||
У меня к вам немного странный вопрос. Он возник у меня при попытке упрощения написания классов под Symbian. Суть вопроса следующая. Мне нужно написать макрос, заменяющий стандартные для Symbian-классов функции. Вот одна из них:
При написании макроса возникает проблема с передачей параметров – макрос должен получать два списка параметров (переменной длины) – формальные и фактические (например, (int a, float b) и (a,b)) и вставлять их в соотв. местах. Если бы я мог средствами препроцессора получить из формальных параметров фактические (например, (int a, float b) -> (a,b)), то проблемы бы не стояло – я бы передавал макросу переменный список формальных параметров (используя оператор …). Однако, как мне кажется, это за гранями возможности препроцессора, т.е. мне придётся вручную передавать фактические параметры. Но как тогда быть с отделением формальных параметров от фактических? Если заключать каждый список в скобки, то можно решить поставленную задачу. Так она решалась при использовании компилятора VC++:
Однако в моей задаче целевым компилятором является GCC, который пресекает подобную практику сообщениями ошибки: “ pasting "NewLC" and "(" does not give a valid preprocessing token”. Жду вашего совета. Спасибо. |
| Автор: SABROG 5.2.2008, 23:52 |
| Сорри за оффтопик, а кто-то считает C++ кроссплатформенным... MSVC, GCC, BCC - у каждого свой стандарт, точно также как у MSSQL, MySQL, PosgreSQL, Oracle, SQLITE, FireBird... |
| Автор: JackYF 5.2.2008, 23:59 | ||
попробуй заменить на
|
| Автор: MAKCim 6.2.2008, 00:07 |
| JackYF, и что? в данном контексте скобки использовались для группировки множества параметров в GCC такое недопустимо Добавлено через 1 минуту и 15 секунд твой способ не позволит отличить формальные и фактические параметры |
| Автор: Mayk 6.2.2008, 09:36 | ||||||
я одного не понял --- а смысл так делать?
Добавлено @ 09:38 расскажи об этом trolltech'ам. а то ребята бедные не в теме. |
| Автор: Абабо 6.2.2008, 10:38 |
| Ну конечно же! Скобки же не должны обязательно прилегать к имени функции - во истину, всё простое гениально... А то я уже стал изощраться с конструкциями типа COMMON_NEWLC(MyClass,SEP(int a, float b),SEP(a,b)), потом же оказалось что мой VC++ 2003 (который я использую для отладки на эмуляторе) не поддерживает макросы с переменным числом параметров... Спасибо всем, а Mayk - особенно! |
| Автор: SABROG 6.2.2008, 11:24 | ||
Я не о том, что невозможно сделать кроссплатформенный проект. А о разности исполнения стандарта. Посмотри хотябы на спецификацию шаблонов, MSVC позволяют ее производить внутри класса, а GCC нет. В итоге C++ код, который должен быть кроссплатформенным вынужден использовать препроцессорные средства, чтобы проверить под каким из компиляторов производится сборка. А из-за разности алгоритма оптимизации создаются объектные файлы, которые могут не собираться с ошибками о всяких unresolved external, а на MSVC все ок. Еще есть косяки с пропиской области видимости объекта, там где MSVC схватает - GCC подавится. Еще в GCC есть тип long long , разные версии msvc его понимают по-разному. Или вот препроцессорная команда #pragma вообще для каждого компилятора разная, а MSVCшники упорно вставляют туда какое-нибудь подключение .lib файла и считают это нормальным. На самом деле подводных камней очень много. Поэтому, если даже библиотека Qt сама кроссплатформенная, то вот приложения написанные с использованием Qt кроссплатформенными могут и не быть, даже если не используют системные API или сторонние библиотеки, которые были написанды для винды. Достаточно писать исходник только под msvc. Т.ч. для программиста желающиего писать кроссплатформенный софт правильно было бы выбрать mingw, если он пишет под виндой. |
| Автор: JackYF 6.2.2008, 11:49 |
Ну да, она есть. Была и будет. И дальше что? |
| Автор: Mayk 6.2.2008, 12:33 | ||||||||||||
С каких пор оптимизатор влияет на mangling?
С какой версии MSVC понимает long long как тип, а не как синатксическую ошибку?
Всегда?
Что такое прописка области видимости?
Могут и не быть. А могут и быть. So what?
Этот фрагмент я не понял. |
| Автор: SABROG 6.2.2008, 13:37 |
| Если чесно, не хочеться углубляться в тему переносимости, тем более что это оффтопик. Просто недавно пытался добавить возможность сборки одного проекта с помощью mingw, так он собирается msvc. Пришлось исправлять исходники в некоторых местах, столкнулся как-раз с теми проблемами, что описал выше. Unresolved External побороть мне так и не удалось, т.к. для этого надо проследить всю цепочку наследования класса, для меня это оказалось слишком сложно, т.к. вся цепочка достаточно большАя часть проекта, а сэмулировать проблему на мелкой программе не удалось. Mangling даже не при чем, т.к. в проекте не линковались библиотеки собранные на других компиляторах. Просто тесты показали, что в зависимости от уровня оптимизации методы и данные могут либо экспортироваться, либо не экспортироваться, т.к. если переменная или метод не используется они "киляются"... Спорить не с кем не буду, перечитал достаточно статей и форумов на эти темы, говорю что знаю, а уж за деталями лезте сами в поисковик... |
| Автор: tsrtg 12.2.2008, 01:41 | ||
Все три установленные у меня версии MSVC (7.1, 8.0 и 9.0) понимают long long именно как 64-битный целочисленный тип. |