#ifdef mylib_unicode
typedef wchar_t mylib_char;
#else
typedef char mylib_char;
#endif
Unicode и ASCII строковые константы
Код:
и использую его дальше для всех переменных и аргументов функций. Но как быть с константами? Я попытался сделать так:
Код:
#ifdef mylib_unicode
#define PFX L
#else
#define PFX
#endif
.......
mylib_char sz[]=PFX"some string";
mylib_char c=PFX'a';
#define PFX L
#else
#define PFX
#endif
.......
mylib_char sz[]=PFX"some string";
mylib_char c=PFX'a';
но Борланд не компилирует, символ L он видит как переменную, а не префиx :(.
Констант довольно много, большие массивы строк, сравнения с символами и т.п. Очень не хочется все их определять по два раза. Может быть у кого-нибудь была подобная проблема и есть хорошее решение? Заранее благодарен.
Цитата: vagran
Такая проблема: пишу библиотеку для своих приложений, которая должа компилироваться в двух версиях: Unicode и ASCII. Как это обычно и делается, определяю тип символа таким образом:
и использую его дальше для всех переменных и аргументов функций. Но как быть с константами? Я попытался сделать так:
но Борланд не компилирует, символ L он видит как переменную, а не префиx :(.
Констант довольно много, большие массивы строк, сравнения с символами и т.п. Очень не хочется все их определять по два раза. Может быть у кого-нибудь была подобная проблема и есть хорошее решение? Заранее благодарен.
Код:
#ifdef mylib_unicode
typedef wchar_t mylib_char;
#else
typedef char mylib_char;
#endif
typedef wchar_t mylib_char;
#else
typedef char mylib_char;
#endif
и использую его дальше для всех переменных и аргументов функций. Но как быть с константами? Я попытался сделать так:
Код:
#ifdef mylib_unicode
#define PFX L
#else
#define PFX
#endif
.......
mylib_char sz[]=PFX"some string";
mylib_char c=PFX'a';
#define PFX L
#else
#define PFX
#endif
.......
mylib_char sz[]=PFX"some string";
mylib_char c=PFX'a';
но Борланд не компилирует, символ L он видит как переменную, а не префиx :(.
Констант довольно много, большие массивы строк, сравнения с символами и т.п. Очень не хочется все их определять по два раза. Может быть у кого-нибудь была подобная проблема и есть хорошее решение? Заранее благодарен.
В VC++ я не заморачивался со своими макросами а писал _T(строковая константа).
Код:
#define _T(x) L ## x
теперь пытаюсь понять, как это работает :). Спасибо, проблема решена.
#ifdef UNICODE
...
#endif
и, опять же в той же визуальной студии был точно такой же тип, как объявляешь ты -- TCHAR
Цитата:
по поводу mylib_unicode, опять же в визуальной студии это делалось без дополнительных дефайнов, а в юникодном проекте уже есть заранее определённый дефан - UNICODE
#ifdef UNICODE
...
#endif
и, опять же в той же визуальной студии был точно такой же тип, как объявляешь ты -- TCHAR
#ifdef UNICODE
...
#endif
и, опять же в той же визуальной студии был точно такой же тип, как объявляешь ты -- TCHAR
Версия моей библиотеки никак не должна зависеть от того, явяется ли весь проект юникодным или нет.
А по поводу вышеприведённого дефайна: порылся в спецификации C/C++ и познал для себя операторы препроцессора # и ##. Я в шоке. Никогда не думал, что можно, например, сделать так:
Код:
#define str(x) # x
#define INC(x) version_ ## x
#include str(INC(4).h)//после препроцессора будет #include "version_4.h"
#define INC(x) version_ ## x
#include str(INC(4).h)//после препроцессора будет #include "version_4.h"
Всё, пойду рисовать транспарант "C рулит, асм подруливает, всё остальное - отстой" :)
Цитата: vagran
Версия моей библиотеки никак не должна зависеть от того, явяется ли весь проект юникодным или нет.
А по поводу вышеприведённого дефайна: порылся в спецификации C/C++ и познал для себя операторы препроцессора # и ##. Я в шоке. Никогда не думал, что можно, например, сделать так:
Всё, пойду рисовать транспарант "C рулит, асм подруливает, всё остальное - отстой" :)
А по поводу вышеприведённого дефайна: порылся в спецификации C/C++ и познал для себя операторы препроцессора # и ##. Я в шоке. Никогда не думал, что можно, например, сделать так:
Код:
#define str(x) # x
#define INC(x) version_ ## x
#include str(INC(4).h)//после препроцессора будет #include "version_4.h"
#define INC(x) version_ ## x
#include str(INC(4).h)//после препроцессора будет #include "version_4.h"
Всё, пойду рисовать транспарант "C рулит, асм подруливает, всё остальное - отстой" :)
Прочитав твой пост я немного засомневался и накатал такой примерчик:
Код:
[SIZE=2][COLOR=#0000ff]#include[/COLOR][/SIZE][SIZE=2][COLOR=#a31515]"iostream"[/COLOR][/SIZE]
[SIZE=2][COLOR=#0000ff]using[/COLOR][/SIZE][SIZE=2] std::cout;[/SIZE]
[SIZE=2][COLOR=#0000ff]#define[/COLOR][/SIZE][SIZE=2] str(x) # x[/SIZE]
[SIZE=2][COLOR=#0000ff]#define[/COLOR][/SIZE][SIZE=2] INC(x) version_ [/SIZE][SIZE=2][COLOR=#0000ff]#[/COLOR][/SIZE][SIZE=2]# x[/SIZE]
[SIZE=2][COLOR=#0000ff]int[/COLOR][/SIZE][SIZE=2] main() {[/SIZE]
[SIZE=2]cout << str(INC(4).h);[/SIZE]
[SIZE=2]}[/SIZE]
[SIZE=2][COLOR=#0000ff]using[/COLOR][/SIZE][SIZE=2] std::cout;[/SIZE]
[SIZE=2][COLOR=#0000ff]#define[/COLOR][/SIZE][SIZE=2] str(x) # x[/SIZE]
[SIZE=2][COLOR=#0000ff]#define[/COLOR][/SIZE][SIZE=2] INC(x) version_ [/SIZE][SIZE=2][COLOR=#0000ff]#[/COLOR][/SIZE][SIZE=2]# x[/SIZE]
[SIZE=2][COLOR=#0000ff]int[/COLOR][/SIZE][SIZE=2] main() {[/SIZE]
[SIZE=2]cout << str(INC(4).h);[/SIZE]
[SIZE=2]}[/SIZE]
[SIZE=2]Результат: INC(4).h[/SIZE]
Цитата:
Прочитав твой пост я немного засомневался и накатал такой примерчик:
Код:
#include"iostream"
using std::cout;
#define str(x) # x
#define INC(x) version_ ## x
int main() {
cout << str(INC(4).h);
}
Результат: INC(4).h
И правда немного не до конца я разобрался. Препроцессор после первого прохода сразу же может сделать строку и не раскрывает внутреннй макро. Попробуй так:
Код:
#include"iostream"
using std::cout;
#define str(x) # x
#define xstr(x) str(x)
#define INC(x) version_ ## x
int main() {
cout << xstr(INC(4).h);
}
using std::cout;
#define str(x) # x
#define xstr(x) str(x)
#define INC(x) version_ ## x
int main() {
cout << xstr(INC(4).h);
}
Кажется, я уже говорил, что препроцессор всего лишь обрабатывает текст, первым встречает str и сморит его define, получается строка "INT(4).h", а все, что в кавычках, препроцессор не сморит.
Цитата:
Кажется, я уже говорил, что препроцессор всего лишь обрабатывает текст, первым встречает str и сморит его define, получается строка "INT(4).h", а все, что в кавычках, препроцессор не сморит.
Не видел, где ты это говорил, но
Код:
#include"iostream"
using std::cout;
#define str(x) # x
#define xstr(x) str(x)
#define INC(x) version_ ## x
int main() {
cout << xstr(INC(4).h);
}
using std::cout;
#define str(x) # x
#define xstr(x) str(x)
#define INC(x) version_ ## x
int main() {
cout << xstr(INC(4).h);
}
выводит version_4.h
Если посмотришь на код внимательно, то поймёшь, что после первого прохода получится str(version_4.h), а после второго "version_4.h". Всё очень просто. :)
Код:
[SIZE=2][COLOR=#0000ff]#include[/COLOR][/SIZE][SIZE=2][COLOR=#a31515]"iostream"
[/COLOR][/SIZE][SIZE=2][COLOR=#0000ff]using[/COLOR][/SIZE][SIZE=2] std::cout;
[/SIZE][SIZE=2][COLOR=#0000ff]#define[/COLOR][/SIZE][SIZE=2] str(x) # x
[/SIZE][SIZE=2][COLOR=#0000ff]#define[/COLOR][/SIZE][SIZE=2] xstr(x) str(str(str(x)))
[/SIZE][SIZE=2][COLOR=#0000ff]#define[/COLOR][/SIZE][SIZE=2] INC(x) version_ [/SIZE][SIZE=2][COLOR=#0000ff]#[/COLOR][/SIZE][SIZE=2]# x
[/SIZE][SIZE=2][COLOR=#0000ff]int[/COLOR][/SIZE][SIZE=2] main() {
[/SIZE][SIZE=2][COLOR=#008000]//Сначала str(str(str(INC(4).h)))
[/COLOR][/SIZE][SIZE=2][/SIZE][SIZE=2][COLOR=#008000]//потом аргумент str(str(str(version_4.h)))
[/COLOR][/SIZE][SIZE=2]cout << xstr(INC(4).h);
}
[/COLOR][/SIZE][SIZE=2][COLOR=#0000ff]using[/COLOR][/SIZE][SIZE=2] std::cout;
[/SIZE][SIZE=2][COLOR=#0000ff]#define[/COLOR][/SIZE][SIZE=2] str(x) # x
[/SIZE][SIZE=2][COLOR=#0000ff]#define[/COLOR][/SIZE][SIZE=2] xstr(x) str(str(str(x)))
[/SIZE][SIZE=2][COLOR=#0000ff]#define[/COLOR][/SIZE][SIZE=2] INC(x) version_ [/SIZE][SIZE=2][COLOR=#0000ff]#[/COLOR][/SIZE][SIZE=2]# x
[/SIZE][SIZE=2][COLOR=#0000ff]int[/COLOR][/SIZE][SIZE=2] main() {
[/SIZE][SIZE=2][COLOR=#008000]//Сначала str(str(str(INC(4).h)))
[/COLOR][/SIZE][SIZE=2][/SIZE][SIZE=2][COLOR=#008000]//потом аргумент str(str(str(version_4.h)))
[/COLOR][/SIZE][SIZE=2]cout << xstr(INC(4).h);
}
Сначала подставляется сам xstr, потом просматривается его аргумент, а потом все получившееся заново.
[/SIZE]