#include <iostream>
void problem( const char*& output, const char* input )
{
output = input;
}
int main() {
const char buff[] = "hello";
char* out = nullptr;
problem( const_cast<const char*&>(out), &buff[0] );
out[0] = 'H';
std::cout << &buff[0] << "\n";
}
这段代码打印出“Hello”,这是我刚刚执行未定义行为的证据。为了这样做,我必须使用const_cast。如果你可以用char*初始化const char*&,那么我就不必使用const_cast来调用未定义行为。
但是,有人可能会说:“这与OP发布的确切情况不符!”
这是真的。
const char*& problem2( char*& c ) { return const_cast<const char*&>(c); }
void problem3( const char*& left, const char* right ) { left = right; }
#include <iostream>
int main() {
char* c = nullptr;
char const* buff = "hello undefined behavior";
problem3( problem2(c), buff );
c[0] = 'H';
std::cout << buff << "\n";
}
还会输出 "Hello undefined behavior"。
但是,有人可能会说:"你把 char*&
转换成了 const char*&
,而不是将 char*
转换成 const char*&
。
好的:
void problem3( const char*& left, const char* right ) { left = right; }
const char*& problem4( char x = 0 ) {
static char* bob = nullptr;
if (bob && x)
bob[0] = x;
return const_cast<const char*&>(bob);
}
#include <iostream>
int main() {
char const* buff = "hello problem";
problem3( problem4(), buff );
problem4('H');
std::cout << buff << "\n";
}
再次提到那个罪状明显的大写字母H
(实际上,这是通常表现为大写字母H
的未定义行为)。
int const
和int* const
中,const
是顶层的;在int const*
(与const int*
相同)中,const
不是顶层的,因为它应用于指向的int
,而不是指针本身。一般来说,在 C++ 中,您可以通过“指向”、“引用”、“数组”等构造来构建复合类型。当您以这种方式组成类型时(例如,“指向char
的指针的指针的引用”),您的类型具有分层结构(在我们的情况下是链)。顶层限定符是应用于此结构的顶级节点的限定符。 - Andy Prowl