Re: [问题] 字符指标的问题

楼主: poyenc (发箍)   2019-09-06 23:11:04
这里给的错误讯息不明确, 推文中提到的型别检查变严格也不是原
因. 在讲原因前先来了解赋値/初始化叙述最重要的几个要素:
B = A;
当我们要把 A 赋値给 B 的时候, 至少需要弄清楚以下 3 点:
1. A 的型别为何?
2. B 的型别为何?
3. 可不可以透过隐式转换 (implicit conversion) 将
A 的型别转换到B 的型别?
简单举个例子, 我们都知道以下的程式码是合法的:
int i = 0;
int* pi = &i; // 1. pi's type is int*
void* pv = pi; // 2. pv's type is void*
// 3. valid, convert int* to void*
再回到原本的问题:
char* str = "hello";
在将 string literal 给 char* 物件做初始化之前, 你需要知道它
的型别是什么, 据我所知在 C 和 C++ 内定义的型别不同:
C (n2346) https://bit.ly/2lHYvLe
6.4.5.6
The multibyte character sequence is then used to
initialize an array of static storage duration and
length just sufficient to contain the sequence. For
character string literals, the array elements have type
char, and are initialized with the individual bytes of
the multibyte character sequence.
C++ (n4830) https://bit.ly/2k3F5jL
5.13.5.6
An ordinary string literal has type “array of n const
char” where n is the size of the string as defined
below, has static storage duration, and is initialized
with the given characters.
所以你的程式码效果其实和下面的差不多 (C++):
const char literal[6] = {'h', 'e', 'l', 'l', 'o', '\0'};
char* str = literal;
会有错误的原因在这:
透过隐式转换无法将指标的 constness 给移除.
还有另外一个地方需要注意: 因为 string literal 本身是阵列,
阵列赋値/计算之前会先退化 (decay) 成指标 (也是转型的一种),
错误讯息省略描述这个步骤所以很容易让人误解它的型别. 最后总
结一下编译器做的事情:
1. 取得 "hello" 的型别, 为 const char[6]
2. 因为要赋値, 把 "hello" 阵列退化成 const char*
3. 取得 str 的型别, 为 char*
4. 检查能否透过隐式转换将 const char* 转成 char* (失败)
第一个步骤 C 和 C++ 编译器取得的型别相异, 导致结果也不同,
这也是常常拿网络上的原始码会编不过的原因, 其实 C 和 C++ 是
两个 (只有) 语法相似但本质不同的语言.
作者: kaneson (Lance)   2019-09-07 09:42:00
小弟认为隐转跟字串常数的建立是两回事的, 因为用显转就可解决。原po的问题我过去的记忆不曾遇到, 加上小弟最近在写c#(碰到不给隐转成parent class), 所以认为vs是朝向strong type checking一派的。而且原po的code来源因使用iostream所以应为c++,(用.c丢给gcc/g++不给过) ,再来字串常数的隐转问题用gcc与g++及使用c++17都只有warning, 所以我觉得问题只是微软走严格趋势
作者: loveme00835 (发箍)   2019-09-07 12:18:00
楼上怎么会有因为“只有 warning”所以程式码“不是ill-formed”的结论?
作者: kaneson (Lance)   2019-09-07 17:47:00
因为只是要回答原po问的教学文章贴上却会报错的问题出在编译器差别不是语法或c/c++的差别。code本质对错就看此篇楼主就行了
作者: james732 (好人超)   2019-09-07 22:21:00
感谢回答

Links booklink

Contact Us: admin [ a t ] ucptt.com