C++ 如何定义地址为空的对象?
我想知道如何在C中定义一个引用为null的对象C++ 如何定义地址为空的对象?,c++,c,linker,weak-references,C++,C,Linker,Weak References,我想知道如何在C中定义一个引用为null的对象 // definition of foo ... void * bar = &foo; // bar must be null 有一些方法我可以找到,但没有适合我的需要 __attribute__((weak)) extern int foo; //not working with cygwin/gcc 3.4 __attribute__((at(0))) int foo; //only with rvds #define
// definition of foo
...
void * bar = &foo; // bar must be null
有一些方法我可以找到,但没有适合我的需要
__attribute__((weak)) extern int foo; //not working with cygwin/gcc 3.4
__attribute__((at(0))) int foo; //only with rvds
#define foo (*(int*) 0) //cannot be embedded in a macro
事实上,我更喜欢标准兼容的解决方案c99,但一切都可以
好的
编辑:这样做的原因是,条形图并不总是空的。以下是一个更相关的示例:
// macro that will define foo to a real object or to *null
DECL(foo);
int * bar = &foo;
if(bar) {
// we can call func
func(bar);
} else {
// bar undefined
exit(-1);
}
当然,这仍然不是很相关,因为我可以在我的条件下使用if。这个项目实际上涉及到大的结构、大量的文件、一些编译器、一些cpu目标,以及许多程序员,他们产生错误的概率与他们使用的语法的复杂性成指数关系。这就是为什么我想要一个简单的宏来声明我的foo对象。我肯定遗漏了一些东西,但是void*bar=NULL有什么不起作用呢?您正在尝试创建一个地址为零的符号。最后一个示例可能是在C编译器/语言中实现这一点的唯一方法 最有可能解决问题的方法是查看链接器程序的输入文件。大多数链接器允许您将标签foo定义为零 在unix ld脚本中,这只是:
foo=0 我认为没有标准的方法来定义地址为0的内容。或者更确切地说,它是未定义的,因为这样就可以取消对0的引用,0是未定义的还是特定于平台的?在标准中
你想做什么?好的,这一定是个问题,但是你想要一个值为0的指针吗 怎么样
void * bar = (void*) 0;
你不必这么胡闹:指针只是一个数字,编译器将它与一个类型相关联;如果希望数字为0,请指定0
哦,回答另一个问题,这不是语言与它有任何关系,只是你不一定知道位置0中有什么。我们在使用BSD代码时遇到了很多麻烦,因为在早期的BSD Unice中,*0==0是可靠的。所以人们会写这样的东西
while(*c) doSomething();
因为当他们取消引用字符串末尾的0x00时,它会查看值为0的位置0。不幸的是,在其他平台上不一定如此。在您的类中,您可以覆盖&operator:
class MyClass
{
public:
MyClass() :
m_isNull(true)
{
}
MyClass(int value) :
m_isNull(),
m_value(value)
{
}
int value() const
{
/* If null, throw exception, maybe? */
return m_value;
}
bool isNull() const
{
return m_isNull;
}
/////////////////////////
// Here's the "magic". //
/////////////////////////
MyClass *operator&()
{
if(m_isNull)
return 0;
return this;
}
private:
bool m_isNull;
int m_value;
};
这会产生MyClass用户可能不期望的行为。我不确定在哪里需要或甚至想要这个功能
如果您想获取MyClass实例的真实地址,可以使用boost,如本答案注释中所建议的:
MyClass foo;
MyClass *fooptr = &foo; // fooptr == NULL
fooptr = boost::addressof(foo); // fooptr = &foo (the real address)
也可以使用强制转换,这样就不会调用MyClass::operator&了:
struct DummyStruct {};
MyClass foo;
MyClass *fooptr = &foo; // fooptr == NULL
fooptr = &reinterpret_cast<DummyStruct>(foo); // fooptr = &foo (the real address)
我真的怀疑在标准C99中是否有办法做到这一点。在标准C++中,如果创建对象,则很难引用它,因为定义空指针常量是不定义的,指针常数中的常数积分0是空指针常数。是的,你可以试试INTI;i=0;foo*p=重新解释卡斯蒂;p->doSomething;但该标准没有具体说明reinterpret_cast的作用,只是以一种模糊且依赖于实现的方式
所以,我的下一个问题是,你们在这里想要实现什么。如果你试图以奇怪而有趣的方式扭曲语言,那么根据标准,它不会以这种方式扭曲语言。如果你有合法的使用,它会是什么? 如果你使用C++,你可以使用引用:
int *foo = 0;
int &bar = *foo;
int *foo_addr = &bar; // gives NULL
您需要的是一个包含空地址的引用。这是一种非常糟糕的做法,但这里有:
#ifdef NON_NULL
Foo realFoo;
Foo &foo = realFoo;
#else
Foo &foo = *(Foo*)NULL;
#endif
请不要这样做。自动ptr可能是一个更好的选择。我想你很接近了,只需一步指针间接指向 根据您的代码示例判断,不需要获取foo的地址。 您可以通过创建一个分配和实例化bar的函数来实现所需的功能 因此,不是:
DECL(foo);
int * bar = &foo;
你可以:
#define FOO_IS_NULL 0
int * getFoo()
{
if( FOO_IS_NULL )
{
return 0;
}
int *tmp = malloc(sizeof(int));
*tmp = 1234;
return tmp;
}
int * bar = getFoo();
注意,这将完全消除变量foo
唯一需要注意的是,您现在需要使用freebar。好吧,我们有: C++允许重载运算符,并且有模板来为您工作,但不允许取消空指针。 C允许取消对空指针的引用,只要随后获取地址即可。它还允许将void*指定给指向对象的任何指针。 嗯,那很理想。首先是C部分,非常简单。我不理解你的观点,你不能把它嵌入宏。这对我来说很好
#define foo_ (*(void*) 0)
现在,C++部分。将内容放入nullp.hpp:
struct nullp {
struct proxy {
template<typename T> operator T*() {
return 0;
}
};
proxy operator&() {
return omg();
}
} foo;
现在,您可以使用&foo并将其分配给指向某个对象类型的指针 听着,我很抱歉,但你把这件事弄得太难也太复杂了 如果你想用C语言调用这个东西,你需要一个指向这个函数的指针。例如,你有
/* ptr to 0-ary function returning int */
int (*func)() = NULL ; /* That's all you need. */
// elsewhere ....
int myfunc() { /* do a good thing */ }
func = myfunc ; /* function name *is* its address */
现在,在后面的代码中,您可以
if(!func)
(*func)();
else
/* function not defined */
您不需要搞乱加载程序,也不需要也不应该使用任何快速宏,除非您确实有充分的理由这样做。Th
is是所有标准C.struct oops{struct omg{template operator T*{return 0;}}};omg operator&{return omg;}}}woops;int*p=&woops;assertp==空污秽警告!!嘿,为什么上面的答案不是我会投票的。但不确定是哪个方向。我得问问。。。为什么你需要首先做这个?为什么不是原来的海报需要C99解决方案,不是C++解决方案。我没有C标准,但是在C++的引用中,空指针是不定义的,指针上下文中的常数0是空指针。这就是他要求的。@Thornley,问题是任何有效的东西都可以。同样,这个问题用C++来标注,如果他还想得到第二个,他可以使用TEXBoo:addressof@litb,我已经用它更新了我的答案,并且是一个非boost方法。谢谢。实际上,我们缺少的是OP真正想要完成的任务的线索。请注意,正式取消对空指针的引用是未定义的。不过,标准中对此存在一些不一致之处。上面写的是UB,但有一处写的不是这样:。可能没有编译器会在你的代码上崩溃。这是未定义的行为,根据C++标准。foo正在取消对空指针的引用。这可以做任何事情,包括在最坏的情况下才露面。呃,没关系。我误读了你的陈述。不过,我确实收到了GCC的警告:取消引用“void*”指针。不过,有了这种黑客行为,我确信它可以被安全地忽略,即使我自己也会寻找更好的解决方案。是的,整个东西都是黑客行为,但我相信完全是标准的。comeau似乎也支持这一观点。至少从它没有警告:在C,它是有效的去引用空隙* -在C++中它是无效的。
if(!func)
(*func)();
else
/* function not defined */