3

I see one contradiction of glibc reference and Amendment 1 to C90.

The quote from glibc reference says that wchar_t may be promoted to wint_t:

if wchar_t is defined as char the type wint_t must be defined as int due to the parameter promotion

But AMD1 says this:

Currently, an existing implementation could have wchar_t be int and wint_t be long, and default promotions would not change int to long. Basically, this is due to wchar_t and wint_t being typedefs. Hence, we will not now have wchar_t be promoted to wint_t.

Does anybody know which one is correct?

Are the standards saying that casting to unsigned int and to int in the following two programs is guaranteed to be correct? (I just replaced wint_t and wchar_t to their actual meaning in glibc) (I just replaced wint_t and wchar_t to their actual meaning in glibc)

#include <locale.h>
#include <wchar.h>
int main(void)
{
  setlocale(LC_CTYPE, "en_US.UTF-8");
  unsigned int wc;
  wc = getwchar();
  putwchar((int) wc);
}

--

#include <locale.h>
#include <wchar.h>
#include <wctype.h>
int main(void)
{
  setlocale(LC_CTYPE, "en_US.UTF-8");
  int wc;
  wc = L'ÿ';
  if (iswlower((unsigned int) wc)) return 0;
  return 1;
}
Igor Liferenko
  • 1,499
  • 1
  • 13
  • 28
  • 1
    The first word is "if", so this only applies when it is that way. It is not bound to be. – Kami Kaze Nov 23 '16 at 06:52
  • @KamiKaze But if the statements contradict at least on one case, this is a problem. – Igor Liferenko Nov 23 '16 at 06:53
  • I can't see any contradiction at all. What do you mean? – Kami Kaze Nov 23 '16 at 06:55
  • @KamiKaze Let's consider the case when `wchar_t` is defined as `char` and `wint_t` is defined as `int`. Now, the first extract says that parameter promotion will be enabled, while the second extract says that it will not. – Igor Liferenko Nov 23 '16 at 06:59
  • mhhh I also considered this to be when int and long are used, but you may have a point there. – Kami Kaze Nov 23 '16 at 07:06
  • AMD1 has been irrelevant since 1999 when the C99 standard superseded it (and that has been superseded by C11). If you find the relevant wording in C11, then there's some point, perhaps, in discussing the issue. Otherwise, there's very little point. Note that we've previously discussed the relationship of `wchar_t` and `wint_t`, and established that `wint_t` is the type that `wchar_t` is promoted to when passed in the variable argument portion of the argument list of a function like `printf()` — you had relevant parts of the standard quoted to you. – Jonathan Leffler Nov 23 '16 at 07:15
  • @JonathanLeffler "`wint_t` is the type that `wchar_t` is promoted to" - where this is written in the standard? Is it worth to ask it as a separate question? – Igor Liferenko Nov 23 '16 at 07:17
  • The standard neither requires nor prohibits `wint_t` to be a promoted version of `wchar_t`. Indeed it mentions that `wchar_t` and `wint_t` can be the same type. The wording explains why there's no such requirement. – n. m. could be an AI Nov 23 '16 at 07:17
  • Also, note that the "Hence" clause applies to an old implementation (prior to AMD1) where `wchar_t` and `wint_t` do not follow the rules laid down by AMD1. It says that "if the implementation does not follow the standard rules, the standard rules won't apply". – Jonathan Leffler Nov 23 '16 at 07:18
  • @JonathanLeffler "and established that wint_t is the type that wchar_t is promoted to" --- where? The standard doesn't say anything like that. – n. m. could be an AI Nov 23 '16 at 07:18
  • 2
    Pay attention to the stuff I've been typing at you for the last .... N days where N is depressingly close to a week. I've provided quotes from the standard previously. I am off to bed; I am not going to find the x-refs now, but they are in answers and/or comments (or most likely both) to your last M questions (or, at least, the last M questions of yours where I've felt obliged to try to explain to you the ways of the world). – Jonathan Leffler Nov 23 '16 at 07:20
  • @n.m. what Jonathan refers to is written in the comments to this: http://stackoverflow.com/a/40712469/1487773/ – Igor Liferenko Nov 23 '16 at 07:22
  • @n.m. "the standard neither requires nor prohibits `wint_t` to be a promoted version of `wchar_t`" - does this mean that to make code portable, explicit typecasting must always be done? – Igor Liferenko Nov 23 '16 at 07:23
  • @n.m. `int w; if (iswlower((unsigned int) w) ....` are the standards saying that casting to `unsigned int` here is guaranteed to be correct? (see examples in OP) – Igor Liferenko Nov 23 '16 at 07:26
  • @IgorLiferenko "explicit typecasting must always be done?" -- yes, and the standard shows such cast it in an example of using %lc conversion. – n. m. could be an AI Nov 23 '16 at 07:37
  • No, the standard doesn't even require `int` to be able to hold a wide character. – n. m. could be an AI Nov 23 '16 at 07:42
  • @n.m. I'm considering one implementation - the glibc one. There `wchar_t` is `int` and `wint_t` is `unsigned int`. Considering this, is the typecasting in the examples in OP guaranteed to be correct? – Igor Liferenko Nov 23 '16 at 07:44
  • You don't need to cast a function argument as long as there's a no-varargs prototype in scope, so these casts are redundant at best. I have no idea whether they are correct. – n. m. could be an AI Nov 23 '16 at 07:57
  • 1
    Are you aware that the type of `L'ÿ'` is not necessarily `wchar_t`, but *the unsigned type corresponding to `wchar_t`*. For all UTF-8 locales, its value is 255 with an unsigned type. – chqrlie Nov 23 '16 at 08:03
  • @n.m. these casts are required if you want to avoid compiler warnings such as `warning: conversion to ‘wint_t {aka unsigned int}’ from ‘wchar_t {aka int}’ may change the sign of the result` if `-Wconversion` gcc option is used. I will ask this as a separate question. – Igor Liferenko Nov 23 '16 at 08:13
  • @chqrlie "Are you aware that the type of L'ÿ' is not necessarily wchar_t, but the unsigned type corresponding to wchar_t" - I do not understand what you mean by this, but in glibc `wchar_t` is the *signed type*. "For all UTF-8 locales, its value is 255 with an unsigned type." - I'm unsure what you mean here, but I agree that `ÿ` is `U+00FF` in Unicode – Igor Liferenko Nov 23 '16 at 08:17
  • 1
    The standard does not require a cast here. An implementation may warn you about 100% legal standard-compliant code if it wants to, it's a separate issue. In any case, your replacement of `wint_t` and `wchar_t` is inexplicable as far as the standard is concerned. Use `wint_t` and `wchar_t` if you want to talk about the standard. – n. m. could be an AI Nov 23 '16 at 08:48

0 Answers0