On Thu, 22 Oct 2015, Martin Sebor wrote: > > LC_MESSAGES determines "the language and cultural conventions in which > > messages should be written" (not necessarily the interpretation of > > multibyte characters in that output). > > Yes, but setting LC_CTYPE shouldn't affect the format, language, > or encoding of diagnostic messages, which is what the text quoted > from the GCC page recommends as a mechanism to change the quote > character in diagnostic messages.
LC_CTYPE should affect the interpretation of multibyte character sequences as characters, including on output. That's the standard semantics. That's what all C library functions involving interpretation of multibyte character sequences do. Straightforward use of POSIX library interfaces does not support producing output in a character set other than that specified with LC_CTYPE; e.g. printf expects a format string (possibly resulting from a message catalog) in the LC_CTYPE character set, and does not convert the bytes to another character set. I'm pretty sure POSIX never intended semantics for messages that imply not outputting them using standard printf functions (or that would mean they couldn't be output with wprintf, using wide characters internally and only converting to multibyte on output). Thus, it affects transliteration when the logically desired characters are not available in the LC_CTYPE character set, which is the case here. > If it did, it would mean that programmers would have to adjust > to the language of the source code of the program they're working > with. For example, if part of a program was written assuming, > say a German locale, then Japanese programmers would need to learn > German to understand the compiler output. (Otherwise, if they set > LC_CTYPE to their Japanese locale) the German quotes in the source > code could be interpreted as something else. German quotes are completely irrelevant to source file interpretation. Character sets are only relevant to source file interpretation in order to map sequences of octets to logical source characters (for example, when a source file is in a multibyte character set where \ can form part of another character rather than just being the \ character from the basic source character set - note that such character sets are not valid for locales in a POSIX environment in the GNU system, where valid locale character sets must interpret all ASCII characters the same as in the C locale and not permit them as part of a multibyte character). They never cause characters to be interpreted as quotes (or digits etc.) if the character set does not map them to the quotes (or digits etc.) in the basic C source character set. Again, LC_CTYPE does *not* affect source file interpretation. Your example illustrates why it affecting source file interpretation is a bad idea: the correct character set for source file interpretation is a property of the source file, and source files are routinely transmitted to people using different locales (so need to be considered as made of bytes not locale-dependent characters). Instead, the source file encoding is specified with -finput-charset, which should be specified in your program's Makefiles if something other than UTF-8 is used in a context where it matters. It appears that LC_CTYPE was intended to have affected source file interpretation before GCC 4.0. It turned out that the code in question was unintentionally dead, and, if enabled, it broke things in practice <https://gcc.gnu.org/ml/gcc/2004-05/msg01007.html> (though given a whitelist of POSIX-safe character sets - ones where conversion cannot affect basic source characters, and so cannot affect the identification of comments - and disabling conversion inside comments for such character sets, it might be safer). The relevant documentation text was added in r24879 ("Merge in gcc2 snapshot 19980929.") so we can't tell the rationale for it without someone with access to the gcc2 list archives checking them, but it looks like it may have been related to an always disabled by default option --enable-c-mbchar which was removed in 2003. You could write your "c99" program wrapper to add a -finput-charset= option based on the locale's character set if you so wish (it also needs to do things such as option reordering and handling -O with separate argument - the "gcc" driver deliberately processes -D and -U options in the order they appear on the command line, not following the POSIX rule that -U options take precedence over -D - so you should not expect the "gcc" driver to be usable as "c99" without such adaptation for deliberate differences). I think we should clearly update the documentation to reflect reality regarding source file encoding, and leave it strictly for wrappers such as "c99" to specify -finput-charset= options rather than leaving open the possibility that GCC's own default might change in future. -- Joseph S. Myers jos...@codesourcery.com