Существует множество макросов для отладки, регистрации, отображения стека и т. Д. Один из них:
#define ASSERT_IF_NULL_2(_ptr1, _ptr2) \
ASSERT(_ptr1); \
ASSERT(_ptr2);
Это более упрощенная версия макросов, которые я написал. У меня есть диалоговое окно с настраиваемым утверждением, если утверждение (время выполнения) не удается, регистрирует такую ошибку проверки нуля в файл журнала. Макросы также написаны так, что не указатели проверяются во время компиляции (static-assert).
Теперь я ищу статические утверждения, чтобы проверить, действительно ли два указателя совпадают. Пример:
int* ptr;
ASSERT_IF_NULL_2(ptr, ptr);
Должен вызвать ошибку компилятора, так как оба аргумента макроса одинаковы. Мне все равно, если указатели указывают на одну и ту же память (так как эта штука — время выполнения).
Я пробовал выражение как:
int xx;
xx = 1 / (ptr-ptr);
xx = 1 / (&ptr - &ptr);
Ни один из них не дает ошибку компиляции деления на ноль.
Кроме того, я пробовал с шаблоном, который принимает void*
это аргумент шаблона:
template<void* T>
class Sample{};
Но это не позволяет указателям на локальные переменные передаваться в аргумент нетипизированного шаблона.
я использую VC9, который не поддерживает constexpr
ключевое слово (даже VS2012 нет). Я попытался использовать ‘const’ вместо этого, который не выдает ошибку. Я также использовал выражение как размер массива, который всегда приводит к ошибке.
int array[(&ptr - &ptr)]; // Even with ptrdiff_t
Итак, вы хотите проверить, передается ли одинаковое имя обоим аргументам, верно? Тогда этот простой трюк работает
#define ASSERT_IF_NULL_2(_ptr1, _ptr2)\
{\
int _check_##_ptr1;\
int _check_##_ptr2;\
}\
ASSERT(_ptr1);\
ASSERT(_ptr2);
int main ()
{
int* ptr1;
int* ptr2;
ASSERT_IF_NULL_2 (ptr1, ptr1); // error: redeclaration of `int _check_ptr1'
ASSERT_IF_NULL_2 (ptr1, ptr2); // OK
}
РЕДАКТИРОВАТЬ (ОП, Аджай):
В компиляторе Visual C ++ мы можем использовать ключевое слово для MS __if_exists
дать ошибку через static-assert
:
#define ASSERT_IF_NULL_2(_ptr1, _ptr2)\
{\
int _check_##_ptr1;\
__if_exists(_check_##_ptr2)
STATIC_ASSERT(false, "Same pointer passed twice")
}\
поскольку static_assert
Ключевое слово не существует для компиляторов до VS2010, можно использовать пользовательский STATIC_ASSERT.
Хорошо, решение оказывается простым. использование static_assert
а также Стрингизатор (#):
#define ASSERT_TWO(a,b) static_assert((void*)#a != (void*) #b, "'" #a "' and '" #b "' are same variables passed to ASSERT_TWO.")
Демо-версия:
int *global;
int main()
{
int *local;
ASSERT_TWO(global, local); //should pass
ASSERT_TWO(local, global); //should pass
ASSERT_TWO(global, global); //should fail
ASSERT_TWO(local, local); //should fail
(void)local; //suppress unsused warning!
}
что приводит к очень полезно сообщение об ошибке:
main.cpp: в функции ‘int main ()’:
main.cpp: 18: 5: ошибка: статическое утверждение не выполнено: глобальные и глобальные переменные передаются в ASSERT_TWO.
main.cpp: 19: 5: ошибка: статическое утверждение не выполнено: локальные и локальные переменные передаются в ASSERT_TWO.
Надеюсь, это поможет.
Напоминаю, что это вам не поможет, так как вы используете VC9, но я держу этот ответ, так как он может помочь другим. На данный момент вы можете использовать другое решение, которое генерирует ошибку объявления, которая является менее полезным сообщением об ошибке по сравнению с static_assert
сообщение.
Вы пытаетесь проверить, указывают ли указатели на одну и ту же память или они указывают на одно и то же значение?
В первом случае
xx = 1 / (ptr-ptr);
должно сработать.
во втором случае
xx = 1 / (*ptr-*ptr);
должно сработать.
Попробуйте один из них, может быть:
ASSERT_IF_NULL(ptr1 == ptr1);
ASSERT(ptr1 != ptr2)
Как указано Nawaz, вы хотите ошибку компиляции, поэтому попробуйте это:
1/(ptr1 != ptr2);
1/static_cast<int>(ptr1 != ptr2);
static_assert(ptr1 != ptr2, "Pointers are different") //if you dont use c++0x look here:http://stackoverflow.com/a/1664651/258418