Path: csiph.com!eternal-september.org!feeder.eternal-september.org!reader01.eternal-september.org!.POSTED!not-for-mail From: Keith Thompson Newsgroups: comp.lang.c++ Subject: Re: An example: code to list exports of a Windows DLL. Date: Tue, 20 Aug 2019 14:59:41 -0700 Organization: None to speak of Lines: 114 Message-ID: References: Mime-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit Injection-Info: reader02.eternal-september.org; posting-host="eda0362a42d89c1a502f45f546af142c"; logging-data="25728"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX19uLYYjpcmmT9pW/EIupn2D" User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/23.1 (gnu/linux) Cancel-Lock: sha1:rVqRL1ubYIYZ8mB8Q6EVzjM5Qk4= sha1:f7PuqTfEWVrOOVX/rTCJEiAa50Q= Xref: csiph.com comp.lang.c++:67823 David Brown writes: > On 20/08/2019 11:18, Keith Thompson wrote: >> David Brown writes: >>> On 20/08/2019 03:31, Keith Thompson wrote: >>>> "Alf P. Steinbach" writes: >>>>> On 19.08.2019 21:44, Richard wrote: >>>>>> "Alf P. Steinbach" spake the secret code >>>>>> thusly: >>>>>> >>>>>>> The $ things in the following code are macros from the specified >>>>>>> header-only library on GitHub. >>>>>> >>>>>> Can you tell me where in the standard it allows for $ to be part of an >>>>>> identifier? >>>>>> >>>>>> I'm looking at 5.10 in N4659 (Draft C++17) and don't see it. >>>>> >>>>> In the future you might risk that people think you're a total novice, >>>>> one who doesn't even know the basics of identifiers in C++. >>>> >>>> Then I'll risk the same thing. Can you explain where C++17 permits $ >>>> in identifiers (or where it permits compilers to permit it)? >>> >>> It doesn't. >>> >>>> I believe that both foo$bar and foo\u0024bar violate a diagnosable rule >>>> and therefore require a diagnostic from any conforming compiler (which >>>> implies that gcc is non-conforming). >>> >>> You get the warning with "-Wpedantic" and an appropriate "-std" C++ >>> standard (and perhaps an appropriate version of gcc). >> >> Can you demonstrate that? I haven't been able to do so, with several >> versions of g++ (up to and including a bleeding-edge version I built >> from source a week and a half ago). Here's the test case I used: >> >> #include >> int main() { >> const int foo$bar = 42; >> std::cout << foo$bar << "\n"; >> } >> >> compiled with "g++ -Wpedantic -std=c++17". No warning from any version >> I have on my system. >> > > I was playing on , with just: > > int a$ = 1; > > "--std=c++03 -Wpedantic" gives a warning (testing with gcc trunk). > --std=c++11 and --std=c++17 do not. (C++98 also warns.) All editions of the C++ standard allow universal-character-names in identifiers, and all restrict them to ranges listed in a table (the table does not include the code for '$'). C++11 (and apparently C++14) add the "other implementation-defined characters" wording, which means that a compiler *may* permit '$' in identifiers (and needn't warn about it). C++17 dropped it according to the drafts I have. As far as I can tell, no version of g++ warns about '$' in an identifier with "-Wpedantic -std=c++17". My reading of the C++17 standard is that such a warning is required, making g++ non-conforming. It appears that gcc warns about '$' in identifiers with -std=c++98 and -std=c++03, and does not warn with -std=c++11 or higher. It looks like the gcc maintainers responded to the addition of "other implementation-defined character" in C++11, but did not respond to its removal in C++17. clang supports '$' in identifiers as an extension, but always warns about them with "-std=c++... -Wpedantic", which is conforming behavior for all versions of the standard. [...] > I have C11 and C++14 standards conveniently at hand, and both have > "other implementation-defined character" clauses. > > If C++17 does not have that, would a $ in an identifier constitute > undefined behaviour (since it is not defined in the standard), and > therefore a compiler can support it, or would it constitute a syntax > error (requiring a diagnostic for conformity) ? It would be a violation of a *diagnosable rule*, requiring at least a warning. I don't think it's a syntax error, but there's no required distinction between syntax errors and other kinds of diagnosable errors. The rule it violates is in N4700 5.10 [lex.name] paragraph 1: Each universal-character-name in an identifier shall designate a character whose encoding in ISO 10646 falls into one of the ranges specified in Table 2. ('$' is not in Table 2.) That wording in the C standard would imply that the behavior is undefined (or that it's a "constraint violation", if it's in an explicitly marked constraint) but C++ [intro.compliance] says: The set of diagnosable rules consists of all syntactic and semantic rules in this document except for those rules containing an explicit notation that “no diagnostic is required” or which are described as resulting in “undefined behavior”. The effect is the same: a diagnostic is required. (If the implementation chooses to produce an executable after printing the required diagnostic, I suppose the behavior is undefined by omission.) -- Keith Thompson (The_Other_Keith) kst-u@mib.org Will write code for food. void Void(void) { Void(); } /* The recursive call of the void */