Why fputwc()
, putwc()
and putwchar()
take argument of type wchar_t
instead of wint_t
?
This contradicts corresponding non-wide character functions fputc()
, putc()
and putchar()
, which take int
, not char
.

- 869
- 1
- 11
- 27

- 1,499
- 1
- 13
- 28
1 Answers
That is because wchar_t
is required to hold an WEOF
value and char
is not required to hold an EOF
value.
For char
, the fputc()
, putc()
and putchar()
functions need to accept values which can hold both values in the unsigned char
and EOF
range, where EOF
can be a negative number so a int
is required to hold them both.1
Whereas wchar_t
itself is required to hold a WEOF
character as well as the biggest locale.2 WEOF
represents a value which fits inside wchar_t
but doesn't overlap with any locale.3
This is made more confusing because of the the names of char
and wchar_t
, you shouldn't see wchar_t
as a char
but more as a int
which size isn't dependent on the architecture but on the size of the biggest locale (and on the value of WEOF
).4
1 Why putchar, toupper, tolower, etc. take a int instead of a char?
2 Quoting ISO/IEC 9899:201x 7.19.2:
WEOF
which expands to a constant expression of typewint_t
whose value does not correspond to any member of the extended character set. It is accepted (and returned) by several functions in this subclause to indicate end-of-file, that is, no more input from a stream. It is also used as a wide character value that does not correspond to any member of the extended character set.
The macro
WEOF
evaluates to a constant expression of typewint_t
whose value is different from any member of the extended character set.
wchar_t
Type whose range of values can represent distinct codes for all members of the largest extended character set specified among the supported locales.In c++,
wchar_t
is a distinct fundamental type (and thus it is not defined in<cwchar>
nor any other header).In c, this is a
typedef
of an integral type.
-
Why in this C code gcc issues no warning? `void f(char c) {} void main(void) {f((int)65);}` Isn't there argument type mismatch? Why the following code does not issue no warning either? `...putwchar(getwchar());...` According to the definitions, argument of `putwchar` is of type **wchar_t**, but return value of `getwchar` is of type **wint_t**. Again - type mismatch. Why the warning is not produced by the compiler? – Igor Liferenko Sep 26 '16 at 01:19
-
If **wchar_t** is required to hold an `WEOF` value, why **wint_t** exists? – Igor Liferenko Sep 26 '16 at 01:22
-
What is the exact value of `WEOF`? Quoting the link http://www.gnu.org/software/libc/manual/html_node/Extended-Char-Intro.html: "ISO 10646 was designed to be a 31-bit large code space". So according to your answer `WEOF` must occupy the place of some valid iso10646 character. This is a contradiction with `EOF`: its value was chosen not to coincide with any valid 8-bit character. Please explain why `WEOF` value is taken from the range of valid iso10646 characters. – Igor Liferenko Sep 26 '16 at 01:31
-
You say that `wchar_t` must hold the value of `WEOF`. But gcc reference says that "WEOF evaluates to a constant expression of type wint_t whose value is different from any member of the extended character set". This is a contradiction. – Igor Liferenko Sep 26 '16 at 08:21
-
`wchar_t` is not a member of the extended character set, it is a type which should represent all the character sets _and_ `WEOF`. The C standard (_9899:201x_ 7.29) also mentions: "`wchar_t` and `wint_t` can be the same integer type." – tversteeg Sep 26 '16 at 08:53
-
Now I understand: ISO 10646 code space takes only 31 bits. But wchar_t (and wint_t) is 32 bits. So, we have 1 extra bit to store WEOF value. But still, having **wchar_t** *and* **wint_t** is confusing. Isn't it? Even if they both exist, shouldn't there be some consistency in using them, but not spontaneously substituting one for another? – Igor Liferenko Sep 26 '16 at 08:59
-
I think that this inconsistency should be reported to glibc developers, because if `wint_t` and `wchar_t` are the same anyway, it is better to be consistent in the function interfaces than to bring confusion. What is your opinion on whether this is worth being reported? – Igor Liferenko Sep 26 '16 at 09:06
-
The first part of the first sentence in your answer is false. – Igor Liferenko Nov 22 '16 at 05:44