确定是否将相同的指针传递给宏
Determine if same pointers are passed to a macro
有一组宏,用于调试,日志记录,堆栈跟踪显示等。其中一个是:
#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
好的,解决方案很简单。使用static_assert
和Stringizing Operator (#):
#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: In function 'int main()':
main.cpp:18:5:错误:静态断言失败:'global'和'global'是传递给ASSERT_TWO的相同变量。
main.cpp:19:5:错误:静态断言失败:'local'和'local'是传递给ASSERT_TWO的相同变量。
在线演示。
希望对你有帮助。
我记得这不会帮助你,因为你正在使用VC9,但我保留这个答案,因为它可能会帮助别人。到目前为止,您可以使用其他产生重声明错误的解决方案,与static_assert
消息相比,这是不太有用的错误消息。
你想检查是否相同的名称传递给两个参数,对吧?那么这个简单的技巧就起作用了
#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
}
EDIT (By OP, Ajay):
在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
您是否试图检查指针是否指向相同的内存,或者它们是否指向相同的值?
第一种情况
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
- 新分配指向函数的指针是否合法?
- 在函数结束后使用指向变量的指针是否安全?
- C++ 返回指向函数内定义的静态数组的指针是否有效?
- 经过最后一个数组元素末尾的指针是否应该等于超过整个数组末尾的指针?
- 传递给放置 new 的指针是否是指向其对象表示形式的非 UB 指针?
- 'this'指针是否可以在 c++ 标头声明中使用?
- C++ 在向量中使用指针是否可能导致指针悬空?
- 唯一指针是否在堆或堆栈上分配内存?
- 将基本实例指针强制转换为派生实例指针是否合法?(实例不是派生实例)
- 当向量增长时,指向向量元素的C++指针是否无效
- 如何判断指针是否是指向数组的指针
- 在类方法中使用 "this" 指针是否是一种好的做法?
- 如何知道指针是否已在其他地方释放
- 结构成员指针是否自动初始化为零?
- 为静态类创建指向对象的指针是否合法?
- 新的自动关键字指针是否会自行删除?
- 创建指针是否超过非数组指针的末尾,而不是从 C++17 中的一元运算符和未定义的行为派生?
- 检查指针是否指向矢量元素
- 如何创建一个带锁的指针数组并检查指针是否空闲?
- 在映射中插入更多元素后,指向 QMap 中元素的指针是否仍然有效?