преобразовать определенную строку макроса в void *

0

Я определил макрос следующим образом:

#define SOME_STRING  "some_string"

и есть поле типа void*. Следовательно, чтобы присвоить этому "some_string", я сделал следующее:

boxFixtureDef.userData = static_cast<void*>(SOME_STRING);

MVS 2012 не жаловался, но Xcode и g++ сообщают об ошибке: invalid static_cast from type 'const char [12]' to type 'void*'. Что не так? Как это исправить?

  • 0
    Это необычно, что любой указатель должен быть явно приведен к указателю void* . Является ли это больше const литья родственной задачи , может быть?
Теги:

4 ответа

7
Лучший ответ

Используйте const_cast для удаления константы. static_cast не может изменять константу переменной.

#include <iostream>

#define MACRO_TEXT "macro-text"

int main()
{
    void *ptr = const_cast<char*>(MACRO_TEXT);
    std::cout << ptr << std::endl;
    return 0;
}

(Вам не нужно явно указывать char * на void *. Это будет сделано неявно).

Быть осторожен. Вам не разрешено изменять значения в userData, потому что исходный указатель является const char []. В этом случае вы можете читать значения из userData.

  • 0
    что я изменить значение в userData?
  • 0
    Например, некоторые коды, такие как static_cast <char *> (userData) [0] = 'a', вызовут неопределенное поведение.
1

Это решило, но я не знаю, насколько это правильно:

boxFixtureDef.userData = reinterpret_cast<void*>(const_cast<char*>(SOME_STRING);
  • 0
    Как я и думал на данный момент;) ...
  • 1
    reinterpret_cast в основном используется для преобразования указателя в / из целого числа (например, uintptr_t) (для переинтерпретации природы), в этом случае вам следует использовать static_cast или просто const_cast с неявным преобразованием в void *.
Показать ещё 1 комментарий
1

static_cast не может отбрасывать константу. Для этого вам нужно const_cast:

static_cast<void*>("something"); // This doesn't compile
static_cast<const void*>("something"); // This does
const_cast<void *>(static_cast<const void*>("something")); // This does, too.

Точно так же неявное преобразование указателей в void * не влияет на cv-квалификаторы:

void *something = "something"; // This doesn't compile
void *something2 = const_cast<char *>("something"); // This does; the char * from the cast is implicitly converted
void *something3 = const_cast<void *>(static_cast<const void*>("something")); // This does, too, but is more verbose.

Однако, если кто-то пытается на самом деле изменить то, на что указывает результирующий указатель, это неопределенное поведение. Поэтому, если возможно, что то, что указывает boxFixtureDef.userData может быть изменено, вы не должны этого делать. Если нет, почему бы просто не сделать его const void *?

0

Просто используйте (void *)(SOME_STRING).

  • 0
    Это не отвечает на то, что просили. Использование кувалды не всегда применимо для вашей текущей заготовки.
  • 0
    Это будет работать, хотя, вообще говоря, более надежно использовать наименьшее возможное приведение из различных приведений, которые есть в C ++
Показать ещё 1 комментарий

Ещё вопросы

Сообщество Overcoder
Наверх
Меню