Ответ 1
Нет, вы не можете что-то подделать.
При использовании препроцессора C можно аргументировать макрокоманду следующим образом:
#define TO_STRING(x) "a string with " #x
и поэтому при использовании результат выглядит следующим образом:
TO_STRING(test)
будет расширяться до: "a string with test"
Есть ли способ сделать обратное? Получить строковый литерал в качестве входного аргумента и создать идентификатор C? Например:
TO_IDENTIFIER("some_identifier")
будет расширяться до: some_identifier
Спасибо за ваши ответы.
EDIT: для тех, кто задается вопросом, что мне нужно для этого:
Я хотел ссылаться на узлы в графе сцены моего 3D-движка по строковым идентификаторам, но в то же время избегать сравнения строк в жестких циклах. Поэтому я решил, что напишу простой инструмент, который будет запускаться на этапе предварительной сборки компиляции и поиска для предопределенной строки - например ID("something")
. Затем для каждого такого токена он вычисляет CRC32 строки между скобкой и генерирует заголовочный файл С#defines, содержащим эти числовые идентификаторы. Например, для строки "something"
это будет:
#define __CRC32ID_something 0x09DA31FB
Затем сгенерированный заголовочный файл будет включен в каждый файл cpp с помощью макросов ID(x)
. Разумеется, ID("something")
будет расширяться до __CRC32ID_something
, поэтому на самом деле то, что увидит компилятор, это простые целочисленные идентификаторы вместо дружественных человеческих строк. Конечно, теперь я просто соглашусь на ID(something)
, но я думал, что использование котировок будет иметь больше смысла - программист, который не знает, как работает макрос ID
, может думать, что something
без кавычек является идентификатором C, когда в действительности такой идентификатор вообще не существует.
Нет, вы не можете что-то подделать.
//unstringify test
enum fruits{apple,pear};
#define IF_WS_COMPARE_SET_ENUM(x) if(ws.compare(L#x)==0)f_ret=x;
fruits enum_from_string(wstring ws)
{
fruits f_ret;
IF_WS_COMPARE_SET_ENUM(apple)
IF_WS_COMPARE_SET_ENUM(pear)
return f_ret;
}
void main()
{
fruits f;
f=enum_from_string(L"apple");
f=enum_from_string(L"pear");
}