K
Keith Thompson
Francis Moreau said:Ok.
All of this means that the (source|execution) characters set is
undefined or rather a local-specific defined.
The *basic* character sets are defined by the standard. The
*extended* character sets are implementation-defined and
locale-specific.
So using '@' character, for example, is valid as long as the local
conventions define it but can be no more valid if the source is used
where the local conventions don't define '@'. So it's basically not
portable but the behaviour is undefined.
As I said, if you transferred the source file to a system that doesn't
have an encoding for the '@' character (apparently some versions of
EBCDIC are like this), then you simply can't have a source file
containing an '@' character. The behavior isn't merely undefined;
there is no behavior, because there can be no such source file.
But yes, if the OS allows '@' characters but the C implementation
doesn't treat '@' as part of its (source|execution) character set,
then the behavior is undefined.
But I still don't see the point of the part of 5.2.1.{3}, which says:
... (except in an identifier, a character constant,
a string literal, a header name, a comment, or a
preprocessing token that is never converted to a
token) ...
I don't see why all of them are exceptions.
I think the idea is that an implementation isn't allowed to quietly
ignore other characters in those contexts, which would be allowed if
the behavior were undefined. For example, an implementation may
permit additional implementation-defined characters in identifiers
('$' is not uncommon); if it does so, it must treat the identifiers xy
and x$y as distinct. Similarly, if you have an '@' character in a
string literal, the compiler must either accept it (after the
source-to-execution conversion in translation phase 5) or issue a
diagnostic.