Как структурировать строку с помощью обратной косой черты - PullRequest
0 голосов
/ 08 марта 2020

Когда я строю свой проект на C ++, компилятор генерирует такой эквивалентный макрос:

#define SOLUTION_DIR "c:\dev\my_project\"

В обычно # определяемом макросе завершающие двойные кавычки будут вызывать ошибки компилятора из-за неопределенной строки, но компилятор может делать что угодно он хочет и делает это доступным для кода буквально, даже если строка недопустима.

Обычный способ расширения значений макросов до C строк:

#define STRINGIZE( x ) #x
#define EXPAND( x ) STRINGIZE( x )

не работает в этот случай из-за неопределенной строки, переданной в качестве аргумента.

std::string s = EXPAND( SOLUTION_DIR );
...
error: newline in constant

Есть ли способ извлечь строковое значение этого макроса и использовать его в моем коде, эквивалентном:

std::string str = R"(c:\dev\my_project\)";

где R - необработанный префикс символов, описанный здесь https://en.cppreference.com/w/cpp/language/string_literal

Примечания:

  • Я пытался переписать эти макросы, используя префикс R, чтобы избежать выхода из финала знак кавычки, но не смог получить функциональную версию.
  • Я могу сказать компилятору определить строку SOLUTION_DIR без окружающих кавычек, но я не могу избежать завершающего backsla sh. В этом случае, однако, я получаю другие предупреждения и ошибки из-за неизвестных escape-последовательностей (\ d) и того факта, что конечная обратная коса sh используется для указания того, что макрос продолжается на следующей строке.

Обновление: Вот контекст для тех, кто считает, что что-то сломано и нуждается в исправлении.

Я использую Visual Studio 2019 (VS). В свойствах проекта «C ++ / Preprocessor / Preprocessor Definitions» можно определить различные макросы в формате:

NAME1=VALUE1;NAME2=VALUE2;...

, которые затем становятся доступны во время компиляции при генерации

#define NAME1 VALUE1
#define NAME2 VALUE2

VS ряд предопределенных макросов (не C ++, а макросы среды сборки) для различных каталогов и других значений (отладка / выпуск, 32 или 64 бит и т. д. c). Они принимают форму $ (имя) и имеют некоторое строковое значение, например:

$(Configuration) Debug
$(SolutionDir) C:\dev\some_project\

Они используются для создания независимых от местоположения настроек проекта, таких как временные или двоичные выходные каталоги, или для установки правильной среды для любой версии проекта (например, Debug / x64).

В моем случае мне нужно получить текущий путь решения непосредственно в моем коде и использовать VS $ (SolutionDir) VS макрос казался самым простым способом сделать это.

Итак, вот как я определил свой макрос SOLUTION_PATH в «Свойствах / Препроцессоре / Определения препроцессора»:

SOLUTION_DIR="$(SolutionDir)

, который переводится в макрос времени компиляции, описанный вначале:

#define SOLUTION_DIR "c:\dev\my_project\"

Однако по умолчанию многие макросы, которые расширяются до путей, в том числе $ (SolutionDir), содержат конечную обратную косую черту sh, которая не может быть удалена, следовательно, "сломанный" макрос выше.

Обычно исполняемый двоичный файл ему не нужно и не следует ничего знать о его каталогах сборки, поэтому макросы, связанные с путями, не обязательно предназначены для определения макросов C ++, и конечная обратная косая черта sh не является проблемой. Но моему проекту нужна эта информация, потому что он сам запускает другие действия по сборке, которые зависят от текущей среды.

Так что это не является неисправностью какого-либо из компонентов, все работает как задумано, просто так получается, что для моего конкретного c Проект было бы очень полезно иметь возможность делать что-то таким образом, даже если это нестандартно.

1 Ответ

0 голосов
/ 09 марта 2020

Я смог сделать эту работу, добавив конечный ".":

SOLUTION_DIR="$(SolutionDir)."

, что приводит к эквиваленту:

#define SOLUTION_DIR "C:\dev\my_project\."

, который указывает на тот же каталог и теперь компилируется без ошибок.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...