C-> С++ Автоматически вводить указатель void в указатель типа в С++ в #define в случае типа не указывается (C-стиль) [MSVS]
Привет!
Я использовал следующий макрос C, но в С++ он не может автоматически отличать void*
до type*
.
#define MALLOC_SAFE(var, size) { \
var = malloc(size); \
if (!var) goto error; \
}
Я знаю, я могу сделать что-то вроде этого:
#define MALLOC_SAFE_CPP(var, type, size) { \
var = (type)malloc(size); \
if (!var) goto error; \
}
Но я не хочу переписывать большую часть кода, где использовался MALLOC_SAFE
.
Есть ли способ сделать это без указания типа макроса? Возможно, некоторые MSVC 2005 #pragma
/__declspec
/other?
p.s.: Я не могу использовать компилятор C, потому что мой код является частью (одним из сотен модулей) большого проекта. А теперь это на С++. Я знаю, я могу создать свой код отдельно. Но это старый код, и я просто хочу его быстро перенести.
Вопрос о void * casting;) Если это невозможно, я просто заменим MACRO_SAFE на MACRO_SAFE_CPP
Спасибо!
Ответы
Ответ 1
Я не рекомендую это делать; это ужасный код, и если вы используете C, вы должны скомпилировать его с помощью компилятора C (или, в Visual С++, в виде файла C)
Если вы используете Visual С++, вы можете использовать decltype
:
#define MALLOC_SAFE(var, size) \
{ \
var = static_cast<decltype(var)>(malloc(size)); \
if (!var) goto error; \
}
Ответ 2
Чтобы ответ Джеймса был еще более грязным, если у вас нет поддержки decltype
, вы также можете это сделать:
template <typename T>
class auto_cast_wrapper
{
public:
template <typename R>
friend auto_cast_wrapper<R> auto_cast(const R& x);
template <typename U>
operator U()
{
return static_cast<U>(mX);
}
private:
auto_cast_wrapper(const T& x) :
mX(x)
{}
auto_cast_wrapper(const auto_cast_wrapper& other) :
mX(other.mX)
{}
// non-assignable
auto_cast_wrapper& operator=(const auto_cast_wrapper&);
const T& mX;
};
template <typename R>
auto_cast_wrapper<R> auto_cast(const R& x)
{
return auto_cast_wrapper<R>(x);
}
Тогда:
#define MALLOC_SAFE(var, size) \
{ \
var = auto_cast(malloc(size)); \
if (!var) goto error; \
}
Я расширил эту утилиту (в С++ 11) на мой блог. Не используйте его ни для чего, кроме зла.
Ответ 3
Например, например:
template <class T>
void malloc_safe_impl(T** p, size_t size)
{
*p = static_cast<T*>(malloc(size));
}
#define MALLOC_SAFE(var, size) { \
malloc_safe_impl(&var, size); \
if (!var) goto error; \
}
Ответ 4
Есть ли причина, по которой никто не просто бросает var, ваш аргумент SAFE_MALOC()? Я имею в виду, malloc() возвращает указатель. Вы храните его где-нибудь, который принимает указатель... Есть все виды аккуратных типов, которые другие люди уже указали... Мне просто интересно, почему это не сработало:
#define MALLOC_SAFE(var,size) { \
(* (void **) & (var)) = malloc(size); \
if ( ! (var) ) goto error; \
}
Да... Я знаю. Он больной и бросает тире безопасности прямо из окна. Но прямая трансляция ((void *) (var)) = не всегда срабатывала.