2013-11-15 3 views
1

Я пытаюсь подправить свою среду тестирования для языка сценариев с некоторыми хорошими макросами C, чтобы не писать один и тот же код более одного раза ... Итак, у меня есть код:Ошибка макрокоманды C/C++ с кавычками и обратными косыми чертами

TEST_CASE("Variables", "[vm_variables]") 
{ 
nap_runtime* runtime = nap_runtime_create(0); 
REQUIRE(runtime != 0); 

nap_bytecode_chunk* bytecode = nap_runtime_compile(runtime, 
       "       \ 
        int a;      \ 
        a = 2;      \ 
       " 
       ); 
REQUIRE(bytecode != 0); 
int t = nap_runtime_execute(runtime, bytecode); 
REQUIRE(1 == t); 
REQUIRE(2 == nap_runtime_get_int(runtime, "a")); 
free(runtime); 
} 

Как это прямо сейчас он создает среду выполнения, где он выполняет код (int a; a=2;), и это работает ...

и я думал, чтобы извлечь части создания в макрос, как показано ниже, таким образом, что мне приходится писать только сценарий ... поэтому я придумал:

#define SCRIPT_START nap_runtime* runtime = nap_runtime_create(0);    \ 
       nap_bytecode_chunk* bytecode = nap_runtime_compile(runtime, \ 
       " 

#define SCRIPT_END " \ 
       ); \ 
       int t = nap_runtime_execute(runtime, bytecode); 

TEST_CASE("Variables", "[vm_variables]") 
{ 
SCRIPT_START     \ <<------------- HERE 
    int a;      \ 
    a = 2;      \ 
SCRIPT_END 

REQUIRE(2 == nap_runtime_get_int(runtime, "a")); 
free(runtime); 
} 

И в моей голове это работает хорошо, но компилятор не любит его ... где вот она даст Mes следующее сообщение об ошибке:

test.cpp: error: missing terminating " character 

Я изменился, и изменил его несколько оборотов , все тот же ... Что я делаю неправильно?

EDIT: После компиляции с -E здесь есть соответствующая часть:

44633  {                   
44634  nap_runtime* runtime = nap_runtime_create(0); nap_bytecode_chunk* bytecode = nap_runtime_compile(runtime, " 
44635   int a;                 
44636   a = 2;                 
44637  "      );      int t = nap_runtime_execute(runtime, bytecode);      REQUIRE(1 == t); 
44638 

так кажется \ от линии с SCRIPT_START макрокоманды игнорируется ... а также другие следующие строки , Зачем?

EDIT2 Экспериментируя и с удовольствием с компилятором:

Теперь, я поставил два обратных слэша:

TEST_CASE("Variables", "[vm_variables]") 
{ 
SCRIPT_START     \\ <<------------- HERE 
    int a;      \\ 
    a = 2;      \\ 
SCRIPT_END 

выход через -E является:

44634  nap_runtime* runtime = nap_runtime_create(0); nap_bytecode_chunk* bytecode = nap_runtime_compile(runtime, " \ 
44635   int a; \                 
44636   a = 2; \                 
44637  "      );      int t = nap_runtime_execute(runtime, bytecode);      REQUIRE(1 == t); 

и ошибка почти то же самое:

test.cpp:19:5: error: missing terminating " character 
test.cpp:19:5: error: stray ‘\’ in program 

так независимо, что с двойной косой черты он генерирует «правильный» код, который до сих пор не удается скомпилировать :)

+0

Скажите компилятор на самом деле не компиляции кода, но только запустите препроцессор и посмотрите на предварительно обработанный вывод, чтобы посмотреть, что действительно производится. С помощью, например, GCC или clang вы используете параметр '-E', не знаете, как это сделать в Visual Studio (или других IDE). –

+0

GCC позволяет видеть вывод препроцессора при запуске с помощью 'gcc -E'.Я не знаю, какой компилятор вы используете, но если у него есть режим, позволяющий увидеть предварительно обработанный вывод, я предлагаю попробовать, чтобы увидеть, что может произойти выше. –

+0

Никто еще не указал очевидное: зачем использовать макросы здесь? Это, похоже, приводит к ужасным ошибкам (вроде этого). Единственное, что вы делаете, это создать строку, которую вы передадите в свою функциональность. Почему бы не вызвать функцию, которая принимает строку? – dornhege

ответ

3

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

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

$ cat test.c 
#include <stdio.h> 

#define BEGIN_QUOTE " 
#define END_QUOTE " 

int main() { 
    printf(BEGIN_QUOTE hello world!\n END_QUOTE); 
    return 0; 
} 

$ gcc -Wall test.c 
test.c:3:21: warning: missing terminating " character [enabled by default] 
test.c:4:19: warning: missing terminating " character [enabled by default] 
test.c: In function ‘main’: 
test.c:7:5: error: missing terminating " character 
test.c:7:24: error: ‘hello’ undeclared (first use in this function) 
test.c:7:24: note: each undeclared identifier is reported only once for each function it appears in 
test.c:7:30: error: expected ‘)’ before ‘world’ 
test.c:7:30: error: stray ‘\’ in program 
test.c:7:30: error: missing terminating " character 

Вы должны оставить кавычки вне макросов и записать их в явном виде:

SCRIPT_START 
"   \ 
    int a; \ 
    a = 2; \ 
" 
SCRIPT_END 
+0

Хорошая точка, и я, конечно, не смог рассмотреть. Я удалю свой вводящий в заблуждение ответ. –

Смежные вопросы