如何更改wchar.h以使wchar_t与wint_t具有相同的类型? [英] How to change wchar.h to make wchar_t the same type as wint_t?

查看:165
本文介绍了如何更改wchar.h以使wchar_t与wint_t具有相同的类型?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

wchar_t 是在wchar.h

当前,如果开发人员只想使用wchar_t,他们将无法执行 这不会从编译器获得类型转换警告.如果 将wchar_t设为与wint_t相同的类型,这对双方都有利. 希望同时包含wint_twchar_t的开发人员 程序(例如,如果他们希望不仅在以下情况下编译其代码, glibc)可以执行此操作而不会收到编译器警告.开发者们 只想使用wchar_t(为避免不必要的麻烦,使用wint_t和 显式类型转换)也可以这样做,而不会得到编译器警告. 它不会带来任何不兼容性或可移植性问题,除非如果仅使用wchar_t的代码将在使用原始wchar.h的计算机上编译,则编译器将打印这些讨厌的警告(如果启用了-Wconversion),但是编译后的程序将以完全相同的方式工作.

Currently, if the developers want to use only wchar_t, they can not do this without getting type conversion warnings from the compiler. If wchar_t will be made the same type as wint_t, it will be good for both parties. The developers who want to have both wint_t and wchar_t in their programs (for example if they want their code to be compiled not only under glibc) can do this without getting compiler warnings. The developers who want to use only wchar_t (to avoid unnecessary hassle with using wint_t and explicit typecasting) can also do this without getting compiler warnings. And it will not bring any incompatibility or portability problems, except that if code using only wchar_t will be compiled on the machine which uses original wchar.h, the compiler will print those pesky warnings (if -Wconversion is enabled), but the compiled program will work absolutely the same way.

C标准(9899:201x 7.29)提到:

The C standard (9899:201x 7.29) mentions:

wchar_t和wint_t可以是相同的整数类型.

wchar_t and wint_t can be the same integer type.

此外,在glibc中,宽字符始终 ISO10646/Unicode/UCS-4,因此它们始终使用4个字节.因此,什么都没有 防止使wchar_t与glibc中的wint_t具有相同的类型.

Also, in glibc wide characters are always ISO10646/Unicode/UCS-4, so they always use 4 bytes. Thus, nothing prevents making wchar_t the same type as wint_t in glibc.

但是,似乎glibc的开发人员不想制作wint_twchar_t由于某种原因,其类型相同.因此,我想更改的本地副本 wchar.h.

But it seems that developers of glibc do not want to make wint_t and wchar_t the same type for some reason. As such, I want to change the local copy of wchar.h.

ISO10646/Unicode/UCS-4将2^31值用于扩展字符集 (未使用MSB):

ISO10646/Unicode/UCS-4 uses 2^31 values for the extended character set (MSB being unused):

0xxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx

请注意,一个4字节类型可以容纳2^31个额外值(MSB为"1"):

Notice, that a 4-byte type can hold 2^31 extra values (MSB being "1"):

1xxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx

这些额外值中的任何一个都可以用来表示WEOF,因此 4字节类型可用于保存所有字符集 WEOF.

Any of those extra values can be used to represent WEOF, thus one 4-byte type can be used to hold all the character set and WEOF.

注意,使用修改后的wchar.h无需重新编译glibc,因为 wint_t可以签名或不签名(因为-10xffffffff都具有MSB) 以任何形式表示为"1",并且由于在 ISO10646/Unicode/UCS-4).

Notice, that no recompilation of glibc is necessary to use the modified wchar.h, because wint_t can be signed or unsigned (since both -1 and 0xffffffff have MSB "1", in any representation, and since MSB is not used in ISO10646/Unicode/UCS-4).

wchar_t的定义在以下wchar.h摘录中的某处完成. 如何更改它以使wchar_twint_t具有相同的类型?

Definition of wchar_t is done somewhere in the following excerpt from wchar.h. How to change it to make wchar_t the same type as wint_t?

#ifndef _WCHAR_H

#if !defined __need_mbstate_t && !defined __need_wint_t
# define _WCHAR_H 1
# include <features.h>
#endif

#ifdef _WCHAR_H
/* Get FILE definition.  */
# define __need___FILE
# if defined __USE_UNIX98 || defined __USE_XOPEN2K
#  define __need_FILE
# endif
# include <stdio.h>
/* Get va_list definition.  */
# define __need___va_list
# include <stdarg.h>

# include <bits/wchar.h>

/* Get size_t, wchar_t, wint_t and NULL from <stddef.h>.  */
# define __need_size_t
# define __need_wchar_t
# define __need_NULL
#endif
#if defined _WCHAR_H || defined __need_wint_t || !defined __WINT_TYPE__
# undef __need_wint_t
# define __need_wint_t
# include <stddef.h>

/* We try to get wint_t from <stddef.h>, but not all GCC versions define it
   there.  So define it ourselves if it remains undefined.  */
# ifndef _WINT_T
/* Integral type unchanged by default argument promotions that can
   hold any value corresponding to members of the extended character
   set, as well as at least one value that does not correspond to any
   member of the extended character set.  */
#  define _WINT_T
typedef unsigned int wint_t;
# else
/* Work around problems with the <stddef.h> file which doesn't put
   wint_t in the std namespace.  */
#  if defined __cplusplus && defined _GLIBCPP_USE_NAMESPACES \
      && defined __WINT_TYPE__
__BEGIN_NAMESPACE_STD
typedef __WINT_TYPE__ wint_t;
__END_NAMESPACE_STD
#  endif
# endif

/* Tell the caller that we provide correct C++ prototypes.  */
# if defined __cplusplus && __GNUC_PREREQ (4, 4)
#  define __CORRECT_ISO_CPP_WCHAR_H_PROTO
# endif
#endif

#if (defined _WCHAR_H || defined __need_mbstate_t) && !defined ____mbstate_t_defined
# define ____mbstate_t_defined  1
/* Conversion state information.  */
typedef struct
{
  int __count;
  union
  {
# ifdef __WINT_TYPE__
    __WINT_TYPE__ __wch;
# else
    wint_t __wch;
# endif
    char __wchb[4];
  } __value;        /* Value so far.  */
} __mbstate_t;
#endif
#undef __need_mbstate_t


/* The rest of the file is only used if used if __need_mbstate_t is not
   defined.  */
#ifdef _WCHAR_H

# ifndef __mbstate_t_defined
__BEGIN_NAMESPACE_C99
/* Public type.  */
typedef __mbstate_t mbstate_t;
__END_NAMESPACE_C99
#  define __mbstate_t_defined 1
# endif

#ifdef __USE_GNU
__USING_NAMESPACE_C99(mbstate_t)
#endif

#ifndef WCHAR_MIN
/* These constants might also be defined in <inttypes.h>.  */
# define WCHAR_MIN __WCHAR_MIN
# define WCHAR_MAX __WCHAR_MAX
#endif

#ifndef WEOF
# define WEOF (0xffffffffu)
#endif

/* For XPG4 compliance we have to define the stuff from <wctype.h> here
   as well.  */
#if defined __USE_XOPEN && !defined __USE_UNIX98
# include <wctype.h>
#endif


__BEGIN_DECLS

__BEGIN_NAMESPACE_STD
/* This incomplete type is defined in <time.h> but needed here because
   of `wcsftime'.  */
struct tm;
__END_NAMESPACE_STD
/* XXX We have to clean this up at some point.  Since tm is in the std
   namespace but wcsftime is in __c99 the type wouldn't be found
   without inserting it in the global namespace.  */
__USING_NAMESPACE_STD(tm)

推荐答案

请注意,引入wint_t是因为wchar_t可能是传递给printf()等人时受默认提升"规则约束的类型.这很重要,例如,在调用printf():

Note that wint_t was introduced because wchar_t might be a type subject to 'default promotion' rules when passed to printf() et al. This matters, for example, when calling printf():

wchar_t wc = …;
printf("%lc", wc);

wc的值可能会转换为wint_t.如果要编写类似printf()的函数,而该函数需要使用<stdarg.h>中的va_arg()宏,则应使用类型wint_t来获取值.

The value of wc might be converted to wint_t. If you're writing a function like printf() which needs to use the va_arg() macro from <stdarg.h>, then you should use the type wint_t to get the value.

标准指出,wint_t的类型可能与wchar_t相同,但是如果wchar_t是(16位)short(或unsigned short),则wint_t可能是(32-位)int.对于第一近似值,wint_t仅在wchar_t是16位类型时才重要.当然,完整的规则更加复杂.例如,int可以是16位类型-但这很少有问题.

The standard notes that wint_t might be the same type as wchar_t, but if wchar_t is a (16-bit) short (or unsigned short), wint_t might be (32-bit) int. To a first approximation, wint_t only matters when wchar_t is a 16-bit type. The full rules are, of course, more complex. For example, int could be a 16-bit type — but this is rarely a problem.

7.29扩展的多字节和宽字符实用程序<wchar.h>

7.29.1简介

¶1标头<wchar.h>定义了四个宏,并声明了四种数据类型,一个标记和一个 许多功能. 326)

7.29 Extended multibyte and wide character utilities <wchar.h>

7.29.1 Introduction

¶1 The header <wchar.h> defines four macros, and declares four data types, one tag, and many functions.326)

2声明的类型为wchar_tsize_t(均在7.19中进行了描述);

2 The types declared are wchar_t and size_t (both described in 7.19);

mbstate_t

是除了可以保持转换状态的数组类型以外的完整对象类型 在多字节字符序列和宽字符序列之间转换所需的信息 字符;

which is a complete object type other than an array type that can hold the conversion state information necessary to convert between sequences of multibyte characters and wide characters;

wint_t

是默认情况下未更改的整数类型,参数promotions可以保存任何 对应于扩展字符集成员的值,以及至少一个 与扩展字符集的任何成员都不对应的值(请参见WEOF 下面); 327)

which is an integer type unchanged by default argument promotions that can hold any value corresponding to members of the extended character set, as well as at least one value that does not correspond to any member of the extended character set (see WEOF below);327)

326)参见未来图书馆的指导"(7.31.16).
327) wchar_twint_t可以是相同的整数类型.

326) See ‘‘future library directions’’ (7.31.16).
327) wchar_t and wint_t can be the same integer type.

¶2…和

wchar_t

是整数类型,其值的范围可以代表所有的不同代码 在支持的语言环境中指定的最大扩展字符集的成员;这 空字符的代码值为零.基本字符集的每个成员 当用作整数中的单独字符时,其代码值应等于其值 如果实现未定义,则为字符常量 __STDC_MB_MIGHT_NEQ_WC__.

which is an integer type whose range of values can represent distinct codes for all members of the largest extended character set specified among the supported locales; the null character shall have the code value zero. Each member of the basic character set shall have a code value equal to its value when used as the lone character in an integer character constant if an implementation does not define __STDC_MB_MIGHT_NEQ_WC__.

请参见为什么putchar()fputc()putc()的参数类型不是char 一个地方引用了C标准的默认升级"规则.在信息可用的地方可能还有其他问题.

See Why the argument type of putchar(), fputc(), and putc() is not char for one place where the 'default promotion' rules from the C standard are quoted. There are probably other questions where the information is available too.

这篇关于如何更改wchar.h以使wchar_t与wint_t具有相同的类型?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆