ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

c – 在调用toupper(),tolower()等之前,是否需要转换为unsigned char?

2019-09-11 09:05:00  阅读:397  来源: 互联网

标签:c-3 toupper c undefined-behavior casting


不久之前,StackOverflow上有名望的人在评论中写道,在调用std :: toupper(和类似函数)之前,有必要将char-argument转换为unsigned char.

另一方面,Bjarne Stroustrup没有提到在C编程语言中这样做的必要性.
他只是喜欢使用toupper

string name = "Niels Stroustrup";

void m3() {
  string s = name.substr(6,10);  // s = "Stroustr up"
  name.replace(0,5,"nicholas");  // name becomes "nicholas Stroustrup"
  name[0] = toupper(name[0]);   // name becomes "Nicholas Stroustrup"
} 

(引用自该书,第4版.)

The reference表示输入需要表示为unsigned char.
对我来说,这听起来像每个char都有,因为char和unsigned char具有相同的大小.

那么这个演员是不必要的还是Stroustrup不小心?

编辑:libstdc++ manual提到输入字符必须来自basic source character set,但不会强制转换.我想这是@Keith Thompson的回复所涵盖的,他们都有正面的代表作为签名的char和unsigned char?

解决方法:

是的,toupper的参数需要转换为unsigned char,以避免未定义行为的风险.

char,signed char和unsigned char类型是三种不同的类型. char具有与signed char或unsigned char相同的范围和表示. (普通字符非常常见,能够表示-128 .. 127范围内的值.)

toupper函数接受一个int参数并返回一个int结果.引用C标准,第7.4节第1段:

In all cases the argument is an int, the value of which shall be
representable as an unsigned char or shall equal the value of
the macro EOF . If the argument has any other value, the
behavior is undefined.

(C包含大部分C标准库,并将其定义推迟到C标准.)

std :: string上的[]索引运算符返回一个char值.如果plain char是有符号类型,并且name [0]返回的值恰好是负数,那么表达式

toupper(name[0])

有未定义的行为.

该语言保证,即使普通字符被签名,基本字符集的所有成员都具有非负值,因此初始化

string name = "Niels Stroustrup";

该程序不会冒未定义行为的风险.但是,是的,通常传递给toupper的char值(或者在< cctype> /< ctype.h>中声明的任何函数)需要转换为unsigned char,因此隐式转换为int将不会产生负值并导致未定义的行为.

< ctype.h>函数通常使用查找表来实现.就像是:

// assume plain char is signed
char c = -2;
c = toupper(c); // undefined behavior

可以在该表的范围之外索引.

请注意,转换为无符号:

char c = -2;
c = toupper((unsigned)c); // undefined behavior

不能避免这个问题.如果int是32位,则将char值-2转换为unsigned会产生4294967294.然后将其隐式转换为int(参数类型),这可能会产生-2.

toupper可以实现,因此它对负值表现得很明智(接受从CHAR_MIN到UCHAR_MAX的所有值),但不需要这样做.此外,< ctype.h>中的函数.需要接受值为EOF的参数,通常为-1.

C标准对某些C标准库函数进行了调整.例如,strchr和其他几个函数被重载版本替换,这些版本强制执行const正确性.对< cctype>中声明的函数没有这样的调整.

标签:c-3,toupper,c,undefined-behavior,casting
来源: https://codeday.me/bug/20190911/1804468.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有