【发布时间】:2014-11-04 18:36:50
【问题描述】:
根据C11WG14 draft version N1570:
标题
<ctype.h>声明了几个对分类有用的函数 和映射字符。在所有情况下,参数都是int, 其值应可表示为unsigned char或应 等于宏EOF的值。如果参数有任何其他值, 行为未定义。
这是未定义的行为吗?:
#include <ctype.h>
#include <limits.h>
#include <stdlib.h>
int main(void) {
char c = CHAR_MIN; /* let assume that char is signed and CHAR_MIN < 0 */
return isspace(c) ? EXIT_FAILURE : EXIT_SUCCESS;
}
标准是否允许将char 传递给isspace()(char 到int)?换句话说,char 转换为int 后是否可以作为unsigned char 表示?
这是wiktionary defines "representable":
能够被代表。
char 可以表示为unsigned char 吗? 是的。 §6.2.6.1/4:
存储在任何其他对象类型的非位域对象中的值 由 n
×CHAR_BIT位组成,其中 n 是该对象的大小 类型,以字节为单位。该值可以复制到类型的对象中 unsigned char [n](例如,通过 memcpy);结果的字节集是 称为值的对象表示。
sizeof(char) == 1 因此其对象表示为unsigned char[1],即char 能够表示为unsigned char。我哪里错了?
具体例子,我可以将[-2, -1, 0, 1] 表示为[0, 1, 2, 3]。如果我不能,那为什么?
相关:根据 §6.3.1.3 isspace((unsigned char)c) 是可移植的,如果 INT_MAX >= UCHAR_MAX 否则它是实现定义的。
【问题讨论】:
-
我会说它是否是未定义的行为是未指定的——
char可以是无符号的,所以CHAR_MIN可以是0。对于有符号字符,-1是一个有效值,但它不能表示为unsigned char(它不在此类型的可表示值范围内)。 -
@dyp:它是未指定的还是实现定义的?假设
char是signed(很常见)。我会更新问题 -
@dyp:
signed-ness of plainchar必须记录在案,因此无论是未定义行为还是明确定义,它都只是实现定义的。 -
@Deduplicator 你是对的。它要么是普通的 UB,要么是实现定义的,无论它是否是 UB。
-
@dyp:在评论中回答我的问题:草案在 6.2.5/15 中说 “实现应将 char 定义为具有与签名相同的范围、表示和行为char 或 unsigned char. 45)" 即,它不仅仅是未指定的,它是实现定义的(实现记录选择)。
标签: c language-lawyer c11