我想知道以下定义之间存在什么差异:
// file.cpp:
namespace n
{
static char const * const str1 = "hello";
static char const str2[] = "hello";
}
我想要的行为,我认为他们都提供:
该语言是否有任何差异? 如果存在依赖于实现的行为,我如何调查不同平台上的差异?
(对于这个例子,我对将这些行为与std :: string选项进行对比不感兴趣,但是如果你认为其他读者会感兴趣,也可以随意谈论它。)
答案 0 :(得分:5)
是的,有:一个仍然是数组,另一个是指针。指针和数组不一样。
一个特定的方面可能是使用sizeof
运算符 - 对于指针,它不会导致字符串的长度,它将在数组上(终止的NUL字符也计入,当然)。
答案 1 :(得分:4)
你可以很容易地遇到两者之间的差异,因为一个是数组而另一个是指针。例如,sizeof
将评估n::str1
和n::str2
的不同(即不相关)值。另外,它们都是左值(是什么让你觉得它们不是?),这意味着你可以对它们应用&
并获得完全不同的结果
&n::str1; // evaluates to a `char const *const *` value
&n::str2; // evaluates to a `char const (*)[6]` value
另请注意,第一个是指向一些不可变实现拥有的“字符串文字存储区”的直接指针,而第二个是由“you”拥有的数组,通过复制上述“字符串”中的数据进行初始化字面存储区“。允许实现在整个程序中合并这些实现拥有的字符串文字。例如,您声明使用相同的字符串文字
初始化另一个指针char const *str_another = "hello";
语言保证str_another
不指向n::str2
assert(str_another != n::str2); // will not fail
但它并不能保证str_another
与n::str1
assert(str_another != n::str1); // can fail
答案 2 :(得分:1)
&n::str1
是char const * const *
,但&n::str2
是char const (*)[6]
。
您可以在函数重载分辨率方面获得一些差异,但可能仅在其中一个重载使用引用数组类型时才会出现。
template<typename T>
void f(T); // #1
template<typename T, std::size_t N>
void f(T (&)[N]); // #2
void g() {
f(n::str1); // calls #1, T is char const*
f(n::str2); // calls #2, T is char const, N is 6.
}
此外,正如@ H2CO3指出的那样,sizeof(n::str1)
为sizeof(char const*)
,但sizeof(n::str2)
为6。