Как сделать строку препроцессора, которая работает как с узкой, так и с широкой - PullRequest
5 голосов
/ 26 апреля 2011

Мне нужно сделать два проекта с разными именами.Оба проекта будут использовать один и тот же код.

Поэтому я начал заменять места, которые вызывают старое имя, на препроцессор в stdafx.h с именем APP_NAME

В stdafx.h я поставил

#define APP_NAME _T("My name") 

И когда я нахожу код типа

function(parm1,_T("My old name have a error"));

, я хочу заменить его на

function(parm1, APP_NAME _T(" have a error"));

Но при широком микшировании возникает много ошибок (T ("x")) или L "") с чисто узким ("")

ошибка C2308: объединение несовпадающих строк

Можно ли использовать магию препроцессора для ее преодоления?

Ответы [ 4 ]

2 голосов
/ 26 апреля 2011

Переместите _T туда, где используется макрос, потому что именно там известна правильная кодировка.

#define APP_NAME "My name"
function(parm1, _T(APP_NAME) _T(" have a error"));

Но на самом деле это не должно быть, это ошибка вVisual C ++ 2010. C ++ 0x требует, чтобы (раздел [lex.string]):

На этапе перевода 6 (2.2) смежные строковые литералы объединяются.Если оба строковых литерала имеют одинаковый кодировочный префикс , результирующий конкатенированный строковый литерал имеет кодировочный префикс . Если у одного строкового литерала нет кодировки-префикса , он обрабатывается как строковый литерал того же кодирования-префикса , что и другой операнд .Если строковый литеральный токен UTF-8 находится рядом с широким строковым литеральным токеном, программа некорректна.Любые другие объединения условно поддерживаются поведением, определяемым реализацией.[ Примечание : Эта конкатенация является интерпретацией, а не преобразованием.Поскольку интерпретация происходит в фазе перевода 6 (после того, как каждый символ из литерала был переведен в значение из соответствующего набора символов), начальная необработанность строкового литерала не влияет на интерпретацию или правильность конкатенации.- конечная нота ]

2 голосов
/ 26 апреля 2011

Возможно, проблема в том, что вы определяете макрос APP_NAME, но затем используете NAME позже.Если это не настоящая проблема, то вам просто нужно последовательно использовать _T ("..."), чтобы все строки были правильно добавлены с префиксом (и при условии, что _T расширяется до не более чем широкой или узкой квалифицированной строки в вашей среде).

0 голосов
/ 26 апреля 2011

Нельзя смешивать узкие и широкие строки. Однако, если вы постоянно используете _T (), все будет работать. Убедитесь, что оба проекта и все модули компиляции имеют одинаковую настройку для UNICODE, которая определяет, будет ли _T () "" или L "".

0 голосов
/ 26 апреля 2011

Имеют APP_NAME и APP_NAME_W, один узкий и один широкий. Используйте тот, который подходит в этом контексте.

...