- running into troubles with const member - 4 Updates
- "volatile" on variables and current processors - 7 Updates
- [Jesus Loves You] [announcement] Fast C++ JSON/RJSON parser - 1 Update
- Trying to be generic with the linker (ld instead of g++) - 5 Updates
- An example: code to list exports of a Windows DLL. - 7 Updates
- "C++: Size Matters in Platform Compatibility" - 1 Update
stdcerr <ron.eggler@gmail.com>: Aug 19 09:36PM -0700 Hi, I'm running into an issue with a class design (so I believe) so I'm looking for input on how to improve my broken attempt: Imagine I have a mother class which initializes a QSettings *instance (in the below code the mother is main())that all other classes should use as well. So, I store it as a const private member in my mother class and pass it on to children in their constructors. Along with the QSettings *instance, there also is a name for each child class which will be used to form a group that stores the respective params . I'm running into issues with nme_set(), the compiler says: foo.cpp: In member function 'void foo::nme_set(const QString&)': foo.cpp:8:46: error: passing 'const QString' as 'this' argument discards qualifiers [-fpermissive] void nme_set(const QString &s) {name = s;} and I'm not exactly sure what to change, can anyone help me? How about the class design, is this how "you" do it? Thanks for your time & help! Every effort is much appreciated! #include <QString> #include <QSettings> class foo { Q_OBJECT public: foo(const QSettings *set=nullptr) { if (set) settings = set;} void nme_set(const QString &s) {name = s;} QString nme_get() {return name;} void qux(void); private: const QString name; const QSettings *settings; }; void foo::qux(void) { QString name = nme_get(); settings->beginGroup(name); /* * ... */ settings->endGroup(); } int main (void) { const QSettings *sttngs = new QSettings(QSettings::NativeFormat,QSettings::UserScope,"GNU","scaper",nullptr); foo *inst = foo(sttngs); inst->nme_set("quux"); inst->qux(); return 0; } |
Ian Collins <ian-news@hotmail.com>: Aug 20 04:59PM +1200 On 20/08/2019 16:36, stdcerr wrote: > foo.cpp:8:46: error: passing 'const QString' as 'this' argument discards qualifiers [-fpermissive] > void nme_set(const QString &s) {name = s;} > and I'm not exactly sure what to change, can anyone help me? You have declared name as a const member, so the only place you can set it is in the constructor. If you don't want it set the name in the constructor, don't make it const. > Q_OBJECT > public: > foo(const QSettings *set=nullptr) { if (set) settings = set;} This appears rather convoluted, settings is a const member, so you must set it in the constructor! -- Ian. |
Sam <sam@email-scan.com>: Aug 20 06:46AM -0400 Ian Collins writes: >> foo(const QSettings *set=nullptr) { if (set) settings = set;} > This appears rather convoluted, settings is a const member, so you must set > it in the constructor! settings is not a const member. name is a const member. >> const QString name; >> const QSettings *settings; >> }; But everything else still applies. name is a const member. It can only be initialized in the constructor, specifically in the constructor's initialization section. Since QString has a default constructor, if it is not explicitly initialized it gets default-constructed. Either way, name is const and, by definition, 'name=s' will not work. Because name is const. That's what "const" means. |
stdcerr <ron.eggler@gmail.com>: Aug 20 06:59AM -0700 Thanks Sam & Ian for your time to reply! On Tuesday, August 20, 2019 at 3:46:44 AM UTC-7, Sam wrote: > > This appears rather convoluted, settings is a const member, so you must set > > it in the constructor! > settings is not a const member. Oh, I intended it to be one, I guess it should rather be written QSettings * const settings; then > not explicitly initialized it gets default-constructed. > Either way, name is const and, by definition, 'name=s' will not work. > Because name is const. That's what "const" means. Right, this is how I learnt about the initialization list. So I've refactured my code but It still does not compile, it now looks like this: #include <QString> #include <QSettings> class foo { Q_OBJECT public: foo(const QSettings *set=0, const QString s="") : name(s),settings(set){} QString nme_get() {return name;} void qux(void); private: const QString name; QSettings * const settings; }; void foo::qux(void) { QString name = nme_get(); settings->beginGroup(name); /* * ... */ settings->endGroup(); } int main (void) { const QSettings *sttngs = new QSettings(QSettings::NativeFormat,QSettings::UserScope,"GNU","scaper",0); foo *inst = foo(sttngs, QString("quux")); inst->qux(); return 0; } and the compiler says: foo.cpp: In constructor 'foo::foo(const QSettings*, QString)': foo.cpp:7:85: error: invalid conversion from 'const QSettings*' to 'QSettings*' [-fpermissive] foo(const QSettings *set=nullptr, const QString s="") : name(s),settings(set){} ^ foo.cpp: In function 'int main()': foo.cpp:31:44: error: cannot convert 'foo' to 'foo*' in initialization foo *inst = foo(sttngs, QString("quux")); ^ Makefile:471: recipe for target 'foo.o' failed make: *** [foo.o] Error 1 Why does it still say "invalid conversion from 'const QSettings*' to 'QSettings*'" and what's wrong with my "foo*", I know I could make this go away by just not declaring insta as a pointer but what's the reason for the complaint? Thanks! |
"Chris M. Thomasson" <chris.m.thomasson.1@gmail.com>: Aug 19 04:37PM -0700 On 8/19/2019 3:21 PM, red floyd wrote: >> indicated? > Also, it's long been known and stated here that volatile is insufficient > for any threading purposes. Right. Its not portable, they do not imply any memory barrier at all, some things do some don't, it was never meant for threading. Use std::atomic with _relaxed_ membars to read and write volatiles for a device or something. |
Keith Thompson <kst-u@mib.org>: Aug 19 05:08PM -0700 > DISCLAIMER: C++03 is the latest copy of the standard that I have. > Can someone check a newer version and see if that's still what is > indicated? ISO/IEC 14882:2011(E) 7.1.6.1 [dcl.type.cv] p6-7: 6 If an attempt is made to refer to an object defined with a volatile-qualified type through the use of a glvalue with a non-volatile-qualified type, the program behavior is undefined. 7 [ Note: volatile is a hint to the implementation to avoid aggressive optimization involving the object because the value of the object might be changed by means undetectable by an implementation. See 1.9 for detailed semantics. In general, the semantics of volatile are intended to be the same in C++ as they are in C. — end note ] 1.9 [intro.execution] paragraph 8 says: 8 The least requirements on a conforming implementation are: — Access to volatile objects are evaluated strictly according to the rules of the abstract machine. [...] I don't have a copy of the C++17 standard, but N4700 (a draft of the C++17 standard) 10.1.7.1 [dcl.type.cv] p5-6 says: 5 The semantics of an access through a volatile glvalue are implementation-defined. If an attempt is made to access an object defined with a volatile-qualified type through the use of a non-volatile glvalue, the behavior is undefined. 6 [ Note: volatile is a hint to the implementation to avoid aggressive optimization involving the object because the value of the object might be changed by means undetectable by an implementation. Furthermore, for some implementations, volatile might indicate that special hardware instructions are required to access the object. See 4.6 for detailed semantics. In general, the semantics of volatile are intended to be the same in C++ as they are in C. — end note ] 4.6 [intro.execution] p7 says: 7 The least requirements on a conforming implementation are: (7.1) — Accesses through volatile glvalues are evaluated strictly according to the rules of the abstract machine. -- Keith Thompson (The_Other_Keith) kst-u@mib.org <http://www.ghoti.net/~kst> Will write code for food. void Void(void) { Void(); } /* The recursive call of the void */ |
"Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com>: Aug 20 02:22AM +0200 On 20.08.2019 00:21, red floyd wrote: >> DISCLAIMER: C++03 is the latest copy of the standard that I have. >> Can someone check a newer version and see if that's still what is >> indicated? C++17 $7.1.7.1, paragraphs 5 and 6: [quote] What constitutes an access to an object that has volatile-qualified type is implementation-defined. If an attempt is made to refer to an object defined with a volatile-qualified type through the use of a glvalue with a non-volatile-qualified type, the behavior is undefined. [Note: volatile is a hint to the implementation to avoid aggressive optimization involving the object because the value of the object might be changed by means undetectable by an implementation. Furthermore, for some implementations, volatile might indicate that special hardware instructions are required to access the object. See 1.9 for detailed semantics. In general, the semantics of volatile are intended to be the same in C ++ as they are in C. [/quote] > Also, it's long been known and stated here that volatile is insufficient > for any threading purposes. There is a proposal to deprecate `volatile`. <url: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p1152r2.html> Cheers!, - Alf |
Bonita Montero <Bonita.Montero@gmail.com>: Aug 20 06:08AM +0200 volatile might be still relevant if you implement your own synchronization-primitives or implement lockfree programming. |
David Brown <david.brown@hesbynett.no>: Aug 20 10:05AM +0200 On 20/08/2019 02:22, Alf P. Steinbach wrote: >> for any threading purposes. > There is a proposal to deprecate `volatile`. > <url: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p1152r2.html> It is not a proposal to deprecate "volatile", despite the name of the paper - it is a proposal to deprecate the unreliable and inconsistent aspects which can have wildly different behaviour on different compilers. Volatile loads and stores are very useful, implemented consistently, and the paper here does not suggest removing them at all. Other operations - in particular, things like "x++;" or "x = y = z;" are poorly specified for volatiles, and there is great variation between targets and compilers on how they work. Writing such volatile expressions in code is madness, and it is a good idea to remove them from the language. C++ should also adopt the changes made in C18 regarding volatiles, where the language is changed to describe volatile accesses, not volatile objects. This is consistent with how compilers implement volatile and how programmers often use volatile. (Just because "volatile" is insufficient for many aspects of multithreading, does not mean it is not essential and sufficient for some programming tasks.) |
David Brown <david.brown@hesbynett.no>: Aug 20 10:14AM +0200 On 19/08/2019 22:56, Vir Campestris wrote: > holding it in a register. That was easy. > C++ is designed around multiple processors with non-coherent caches, and > we have memory fences and such to keep things clean. No, it isn't - it is designed around single processors, single threads, and processors that give a simple, serial ordering to everything. Multi-threading and the rest of it is an add-on that came in C++11. Of course, this makes programming for multi-threaded and multi-core systems much easier as there is support in the language. > volatile is no longer adequate for such machines. Volatile alone was never adequate for such machines. Until atomics, locks, etc., made it into the language and library with C++11, you used OS-specific or compiler-specific features for synchronisation, locks, atomic accesses, and so on. In many cases, "volatile" was part of the implementation of these features - but it was never sufficient, and usually supplemented by compiler intrinsics or inline assembly. > I'm reasonably sure that none of the accesses are close enough that > re-ordering would matter. > Andy That all depends on what you mean by "current ARM processors" and what you are trying to do. The "current ARM processors" I mostly use are all single core with in-order execution and no reordering for loads or stores in the hardware - "volatile" is sufficient for many purposes, and can be a lot more efficient than atomics. But that is because my "current ARM processors" are cores for modern microcontrollers, rather than general-purpose multi-core processors. And if you mean multi-core systems, then "volatile" is unlikely to be sufficient on its own. You can't rely on any measure of "distance between accesses" to keep you safe. |
Juha Nieminen <nospam@thanks.invalid>: Aug 20 01:03PM > And it's got lots of use of > volatile in the old way - don't cache this please, another thread may > touch it. volatile does in no way make a variable thread-safe. And it has never been even really meant for that. The main use for volatile is in certain architectures (eg. certain embedded systems) where eg. certain memory locations have more significance to the system than being merely dummy storage for a value. For example, a particular memory location might be mapped by the hardware to be input and output to a port (which may be, for instance, some kind of 7-segment LCD display or the like). Thus writing to that memory location will output the value to that port, and readint that location will read the port. In these architectures telling the compilar that eg. a pointer to that memory location is pointing to a volatile value may be important, as it (usually) prevents the compiler from optimizing away reads and writes to it. In general, for "normal" variables or pointers you don't want to needlessly declare then volatile, because they can become really inefficient, as the compiler usually obey the instruction and literally read and write to that variable in memory every single time it's done in the code. (For example, declaring a loop counter variable volatile for no good reason would be rather silly.) |
rick.c.hodgin@gmail.com: Aug 20 05:57AM -0700 On Sunday, August 11, 2019 at 6:24:00 AM UTC-4, Mr Flibble wrote: > -- > "Snakes didn't evolve, instead talking snakes with legs changed into > snakes." - Rick C. Hodgin Even though I'm no longer posting here I'm in your mind! :-) Keep this signature line and you'll remember me by its presence. Lose this signature line and you'll remember me by its absence. You've arrange your life just so, even in your rebellion. But it's not me you're remembering, Leigh. It's Jesus. Jesus sets souls free, Leigh. He rescues men/women out of judgment. He is the great redeemer. He is life, and He loves you so. The Encounter (2010) https://www.youtube.com/watch?v=oBsqSTZjU7M Always reaching out to save, to increase, to help, to redeem. -- Rick C. Hodgin |
Frederick Gotham <cauldwell.thomas@gmail.com>: Aug 20 04:09AM -0700 I've been doing web searches all morning to try solve this so I'm here now as last resort. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Typically if we want to combine C and C++ in one program, we can do three steps: gcc -c *.c g++ -c *.cpp g++ -o prog *.o So we use 'gcc' to compile the C code. Then we use 'g++' to compile the C++ code. Finally we use 'g++' a second time to link the object files together into one executable file. I'm trying to be as generic as possible here in the final step (i.e. linking), and so I want to replace the second use of 'g++' with 'ld', so something like: gcc -c *.c g++ -c *.o ld -o prog *.o This works fine for the C portion of the program so long as you link with the standard C library like this: ld -lc -o prog *.o But if you also want to link with the C++ library (including the STL), then in theory you can try something like: ld -lc -lc++ -o prog *.o But this doesn't work for me on my 64-Bit x86_64 Ubuntu 18.04 personal computer. I've tried a few different switches to get the C++ standard library (e.g. lstdc++) but none of them work. How do you link the C++ standard library in when linking with 'ld' ? If I run "ld --version" at the command line then I get: GNU ld (GNU Binutils for Ubuntu) 2.30 Copyright (C) 2018 Free Software Foundation, Inc. This program is free software; you may redistribute it under the terms of the GNU General Public Licence version 3 or (at your option) a later version. This program has absolutely no warranty. |
Bart <bc@freeuk.com>: Aug 20 12:25PM +0100 On 20/08/2019 12:09, Frederick Gotham wrote: > But this doesn't work for me on my 64-Bit x86_64 Ubuntu 18.04 personal computer. I've tried a few different switches to get the C++ standard library (e.g. lstdc++) but none of them work. > How do you link the C++ standard library in when linking with 'ld' ? > If I run "ld --version" at the command line then I get: When I wanted to find out how ld was being invoked (from gcc in my case not gc++) I temporarily replaced ld.exe (this was on Windows) with this program that lists the command line parameters: #include <stdio.h> int main (int n, char** a) { for (int i=1; i<=n; ++i) { printf("%d: %s\n",i,*a); ++a; } } Then I ran gcc as normal. This listed some 50 different options passed to ld even for a hello,world program. (Doubtless there will be some existing way of doing this.) This might help highlight what gcc/g++ is adding that is missing in your simpler invocation. (Don't forget to restore the original ld executable. Don't forget to preserve the original either...) |
Frederick Gotham <cauldwell.thomas@gmail.com>: Aug 20 04:34AM -0700 On Tuesday, August 20, 2019 at 12:26:06 PM UTC+1, Bart wrote: > simpler invocation. > (Don't forget to restore the original ld executable. Don't forget to > preserve the original either...) Very cool idea. I was hoping to use 'ld' instead of 'g++' but if it's that complicated then I might not bother. |
Ralf Fassel <ralfixx@gmx.de>: Aug 20 02:05PM +0200 * Frederick Gotham <cauldwell.thomas@gmail.com> | But if you also want to link with the C++ library (including the STL), then in theory you can try something like: | ld -lc -lc++ -o prog *.o | But this doesn't work for me on my 64-Bit x86_64 Ubuntu 18.04 personal | computer. I've tried a few different switches to get the C++ standard | library (e.g. lstdc++) but none of them work. | How do you link the C++ standard library in when linking with 'ld' ? You could run "g++ -v" to see what g++ is doing to get the job done: g++ --help Usage: g++ [options] file... Options: --<snip-snip>-- -v Display the programs invoked by the compiler. But the main question would be: why would you want to run ld directly? I'd rather do g++ -o prog prog.cxx than some (probably version depended) magic... R' |
David Brown <david.brown@hesbynett.no>: Aug 20 02:10PM +0200 On 20/08/2019 13:09, Frederick Gotham wrote: > gcc -c *.c > g++ -c *.o > ld -o prog *.o Why? What benefit do you think you'll get from using "ld" instead of "g++" for the linking? It will just mean adding more manual flags. > But if you also want to link with the C++ library (including the STL), then in theory you can try something like: > ld -lc -lc++ -o prog *.o > But this doesn't work for me on my 64-Bit x86_64 Ubuntu 18.04 personal computer. I've tried a few different switches to get the C++ standard library (e.g. lstdc++) but none of them work. There are a variety of libraries that will be included automatically when you link using "gcc" and "g++". Linking C++ code will require more of these than simpler C code, which is why you get away with it for the C code. > How do you link the C++ standard library in when linking with 'ld' ? > If I run "ld --version" at the command line then I get: Invoke "g++ *.o" or "gcc *.o" with the "-v" flag, and it will print the options. You may not need all of these for manual "ld" flags, but you will no doubt need more than you have. |
"Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com>: Aug 20 02:12AM +0200 On 19.08.2019 21:44, Richard wrote: > 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++. Having called you out on that: I've not yet heard of a practical problem with it with any compiler. However, when Herb Sutter tried this naming scheme on some years after I first did it, he got negative reactions from some people whose company used a critical custom preprocessing step where `$` was significant, and which was sufficiently simple-minded to be misled into doing the Wrong Thing™. So he dropped the scheme, but I don't have to. :) No sane person would e.g. rewrite `#pragma once` to more verbose and ugly and error prone include guards with formally guaranteed behavior just to get that formal guarantee, but if there is a problem with the `$`s, like the aforementioned preprocessing, then you can replace these macro names with their uppercase aliases. Less readable IMO. But YMMV. Cheers & hth., - Alf |
Keith Thompson <kst-u@mib.org>: Aug 19 06:31PM -0700 >> 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)? Earlier editions of the standard, such as C++11, permitted "other implementation-defined characters" in identifiers. This was dropped after Defect Report #1963 pointed out that it was supposedly redundant. http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1963 In N4700 (a more recent C++17 draft), identifiers may contain the 52 upper and lower case letters, the 10 decimal digits, underscores, and universal-character-names. Characters not in the basic source character set are mapped to universal-character-names in translation phase 1, so $ will (probably) be mapped to \u0024 . But universal-character-names in identifiers are only allowed by designate characters in certain ranges (Table 2 in 5.10 [lex.name]), and \u0024 is not in any of those ranges. For example, this program prints "42" when I compile and run it with g++, but clang++ rejects it (it warns about the '$' in an identifier and says that "foo" is undeclared on the "std::cout << ..." line). (I used "-std=c++17 -pedantic" for both.) #include <iostream> int main() { const int foo$bar = 42; std::cout << foo\u0024bar << "\n"; } 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). It's possible that it was intended to permit (but not require) support for $ in identifiers, but that that was overlooked in the response to Defect Report #1963. Perhaps 0024 should be added to Table 2? Or perhaps I'm missing something (always a real possibility). -- Keith Thompson (The_Other_Keith) kst-u@mib.org <http://www.ghoti.net/~kst> Will write code for food. void Void(void) { Void(); } /* The recursive call of the void */ |
David Brown <david.brown@hesbynett.no>: Aug 20 08:42AM +0200 On 20/08/2019 03:31, Keith Thompson wrote: >> 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). > Or perhaps I'm missing something (always a real possibility). What you are missing is that $ is accepted in identifiers in many compilers, and Alf simply does not care that it is not supported in the standards as long as it is supported in the compilers he uses. This is not an unreasonable attitude, if you like the kind of macro libraries he has (I don't personally, but some people do) and he is certainly not alone in it. But I think it would be a better to be much clearer about it being non-standard. Future directions of C++ are seriously considering adding $ for use in metadata (metaclasses, introspection, etc.), which may break his library or at least cause confusion. And there are plenty of compilers that won't accept $ as an identifier letter (such as gcc for the AVR - a perfectly valid, if small and limited, C++ target), and others where it can cause trouble with assemblers which use $ as a comment symbol (68k) or in register names (many, including ARM). As long as Alf's code is for his own use, and he only uses the compilers /he/ chooses, with the compiler flags /he/ chooses, then he is of course free to use $ in his identifiers. But he should not expect others to be as happy with it. |
Keith Thompson <kst-u@mib.org>: Aug 20 02:18AM -0700 >> 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 <iostream> 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. > What you are missing is that $ is accepted in identifiers in many > compilers, and Alf simply does not care that it is not supported in the > standards as long as it is supported in the compilers he uses. Please don't assume that I missed it just because I didn't discuss it. My post was about whether the C++ standard permits compilers to permit $ in identifiers. (I presume we can all agree that compilers aren't *required* to accept $ in identifiers.) C++11 clearly does permit it, since it explicitly allows "other implementation-defined characters" in identifiers. C++17 apparently does not, since it dropped that wording (apparently in the belief that it was redundant, but I don't believe it was). [...] -- Keith Thompson (The_Other_Keith) kst-u@mib.org <http://www.ghoti.net/~kst> Will write code for food. void Void(void) { Void(); } /* The recursive call of the void */ |
Ian Collins <ian-news@hotmail.com>: Aug 20 10:22PM +1200 On 20/08/2019 21:18, Keith Thompson wrote: > } > compiled with "g++ -Wpedantic -std=c++17". No warning from any version > I have on my system. Try clang: $ clang++ -Wpedantic -std=c++17 /tmp/x.cc /tmp/x.cc:3:18: warning: '$' in identifier [-Wdollar-in-identifier-extension] const int foo$bar = 42; ^ /tmp/x.cc:4:21: warning: '$' in identifier [-Wdollar-in-identifier-extension] std::cout << foo$bar << "\n"; ^ 2 warnings generated. $ clang++ --version clang version 8.0.1-svn363027-1~exp1~20190611211629.77 (branches/release_80) -- Ian. |
David Brown <david.brown@hesbynett.no>: Aug 20 01:00PM +0200 On 20/08/2019 11:18, Keith Thompson wrote: > } > compiled with "g++ -Wpedantic -std=c++17". No warning from any version > I have on my system. I was playing on <https://godbolt.org>, 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.) It seems to be quite specific here. clang warns on C++11 and C++17 as well as C++03. So you can get a warning on some choices, but not others. >> compilers, and Alf simply does not care that it is not supported in the >> standards as long as it is supported in the compilers he uses. > Please don't assume that I missed it just because I didn't discuss it. Fair enough. > characters" in identifiers. C++17 apparently does not, since it > dropped that wording (apparently in the belief that it was redundant, > but I don't believe it was). 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) ? |
Frederick Gotham <cauldwell.thomas@gmail.com>: Aug 20 04:09AM -0700 For the past 15 years or so, I've been using "Dependency Walker" for this on MS-Windows and it works great. |
David Brown <david.brown@hesbynett.no>: Aug 20 08:21AM +0200 On 19/08/2019 22:17, Scott Lurndal wrote: > Because it will prevent many Usenet clients from breaking the URL into > multiple lines and it avoids confusion as to whether adjacent punctuation symbols > are part of the URL or not. It also means that the URL will continue to work with many clients, even if it /is/ broken into multiple lines. Lynn, I added the marks to your URL when I made the reply. By now, it will have wrapped to two lines - you can test it and see if it still works as a link for your client. |
You received this digest because you're subscribed to updates for this group. You can change your settings on the group membership page. To unsubscribe from this group and stop receiving emails from it send an email to comp.lang.c+++unsubscribe@googlegroups.com. |
No comments:
Post a Comment