- Why does this work on Xcode ??? - 2 Updates
- An example: code to list exports of a Windows DLL. - 10 Updates
- What is easiest to use static C++ code analyser? - 1 Update
- About getters/setters - 2 Updates
- running into troubles with const member - 5 Updates
- Trying to be generic with the linker (ld instead of g++) - 3 Updates
- Explicitly deduced return type (like "auto foo() -> auto"), is that valid? - 1 Update
- "volatile" on variables and current processors - 1 Update
Tim Rentsch <tr.17687@z991.linuxsc.com>: Aug 22 10:28AM -0700 >> As far as the Standard is concerned these two functions are >> semantically equivalent. > If resource limits are not exceeded. The semantics of a program is what is specified to happen in the abstract machine. Resource limits come into play only when a program is run on an actual machine; they have no bearing on program semantics. > Yes. >> They have exactly the same implications for observable behavior. > No. Please outline a scenario in the abstract machine when the two functions have different observable behavior. >> If one has undefined behavior then so does the other. > No. Please outline a scenario in the abstract machine when one of the two functions unconditionally has undefined behavior and the other does not. >> If one has a risk of undefined behavior then so does the other. > Repeating that claim doesn't make it less incorrect. It isn't the same claim. The first is about undefined behavior that must occur, the second is about undefined behavior that may occur but doesn't have to. (see next) > I'm pretty sure that you inadvertently repeated it because it was > orbiting in your mind, the key thing to communicate. No, I made a separate point to address your individual idea of what "undefined behavior" means. (As a side comment, other people disagree with your view - see this SO question: https://stackoverflow.com/questions/56811284/ does-this-program-with-bounded-recursion-have-undefined-behavior in particular the most highly voted answer.) > But it's trivially false: for a just some orders of magnitude > larger array size I can arrange to consistently crash the > recursive function, while the iterative one will be fine. You point out later that /any/ function call can run out stack space and so (under your view) has a risk of undefined behavior. So my statement is trivially true. >> implementation may choose to compile an iterative definition into >> recursive object code > No, absolutely not. Don't be silly, of course it can. The C and C++ standards don't say anything about how a program is compiled except that the compiled code has to match the observable behavior of the abstract machine. In fact, very much the opposite: program semantics is defined in terms of behavior in the abstract machine, and "conforming implementations are required to emulate (only) the observable behavior of the abstract machine". Observable behavior does not include stack depth. Both the C and the C++ standard explicitly give unbounded latitude as long as the observable behavior requirement is met. >> , as well as vice versa. > Yes, it /can/ transform a recursive one to an iterative one that > uses less resources. I think you are confused about what "observable behavior" means. Observable behavior does not depend on what resources are available. >> also say the C++ standard gives you no guarantee about whether the >> iterative function might result in undefined behavior. > That would follow if your premises were true, but they aren't. You claim they aren't. Please support that claim by providing one of the example scenarios I asked for above. > run a risk, that swimming and flying are somehow on equal terms, > ignores the important real world aspects and focus on a wholly > unreasonable, dangerous academic simplification. As I see it. Practical considerations are a separate concern, which I may take up in a separate response. > to rewrite an iterative function as recursive, then that /would/ > have been that kind of in-effect-sabotage, and then I /would/ have > used derogatory words. ;-) The current standards, back to and including the original C89 standard, deliberately grant sufficient latitude to make arbitrarily poor implementation choices as long as the observable behavior requirement is met. I'm sure this was a conscious decision, and not either an academic one or one divorced from reality. You are very much swimming upstream here: do you really want to say you are smarter than all the people who have participated in the C and C++ working groups to standardize these languages? I hope you will understand if I view these last remarks with a fair amount of skepticism. |
"Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com>: Aug 22 07:50PM +0200 On 22.08.2019 19:28, Tim Rentsch wrote: > very much swimming upstream here: do you really want to say you are > smarter than all the people who have participated in the C and C++ > working groups to standardize these languages? There are 3 main things wrong with that statement: * The idea that I'm arguing a view at odds with the standard. I'm not. Check how many in this group agree with your view of UB: that's 0. * The idea that /if/ one believes the standard is sub-optimal or wrong, one must believe that one is smarter than all the people blah blah. If that were the case then all those non-committee members who have filed Defect Reports against the standard, must be megalomaniacs who think they're very very smart. That's just not so. * It's a purely social argument. > I hope you will > understand if I view these last remarks with a fair amount of > skepticism. [Hark.] I may address the rest of your posting later, trying to give the examples etc. you ask for, because I feel you mean this seriously. And I don't think you think you're smarter than everybody else in this group just for holding an opinion on UB that nobody else here shares. I think you're simply convinced that you're right, that your distinctions are meaningful, and somehow my and others' arguments have failed to move your conviction. Which I think means we're not good enough at presenting our view. Not, that we're wrong. ;-) Cheers!, - Alf (fairly intelligent but at least now not at Mensa level :) ) |
"Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com>: Aug 22 03:38AM +0200 On 21.08.2019 21:41, Keith Thompson wrote: > By accepting identifiers with "$" without a diagnostic in what is > intended to be a conforming mode, g++ is violating the requirements of > the C++ standard. If you disagree, what exactly is your argument? The above responds to what was a coherent /reductio ad absurdum/ argument, now lost in refocusing on and possibly misinterpreting one of the shattered pieces of it. As pointed out by you up-thread it's not the case that accepting the `$` requires a diagnostic in all versions of the standard. g++ is simply not fully up to date regarding C++17 in this respect. But then few compilers, if any, are standard-conforming by default: one needs to cajole them into conformance by applying the relevant set of options. > "diagnostic" in a way that's consistent with that. No implementation > does so or is likely to do so in the future. > I thought your argument was based on "common sense". Yep. > to allow for that). Which is why, in my opinion, the standard *should* > allow compilers to accept $ in identifiers. > [...] Yes, I should have written MPE/IV, the OS we used on the HP3000. Sorry. It's possible that all this is tied to the attempt to remove `$` in ASCII, as I recall instigated by Russia or France, a political thing. I mean, tied by the baffling decision to not include `$` in the C++ basic execution character set. For the new ASCII that I don't remember the name of, we got the (hark) universal currency symbol `¤` as a replacement for `$`. Nobody uses that. It's meaningless except as a political statement, but it's there on my keyboard, taking up one key combination. Cheers!, - Alf |
Keith Thompson <kst-u@mib.org>: Aug 21 07:24PM -0700 > On 21.08.2019 21:41, Keith Thompson wrote: [...] > The above responds to what was a coherent /reductio ad absurdum/ > argument, now lost in refocusing on and possibly misinterpreting one of > the shattered pieces of it. I still can't make any sense of what you've written so far in this thread. Perhaps I'll stop trying. > fully up to date regarding C++17 in this respect. But then few > compilers, if any, are standard-conforming by default: one needs to > cajole them into conformance by applying the relevant set of options. As I said, I did apply the relevant set of options. C++17 does not permit '$' in identifiers, and requires a diagnostic for any program that attempts to use a '$' in an identifier. Earlier editions of the standard do permit implementations to support '$' in identifiers. gcc's lack of a diagnostic in conforming mode "gcc -std=c++17 -Wpedantic" makes it non-conforming. If you agree with that, I don't know what we're arguing about. If you don't, I have yet to see an explanation. I've also suggested that the committee probably did not intend to make a significant change in this area. [...] > ASCII, as I recall instigated by Russia or France, a political thing. I > mean, tied by the baffling decision to not include `$` in the C++ basic > execution character set. I've never heard of any attempt to remove '$' from ASCII, which I believe has not changed since 1967. Do you have a citation for that? '$' is not in the source or execution basic character set, a decision that was made a long time ago. Apparently '$' is not supported in all versions of EBCDIC, or at least doesn't have a consistent code (see the Wikipedia article). And there are no tokens in C or C++ that required $ (or @ or `, the only three printable ASCII characters not in the C or C++ basic character set). > universal currency symbol `¤` as a replacement for `$`. Nobody uses > that. It's meaningless except as a political statement, but it's there > on my keyboard, taking up one key combination. There is no "new ASCII". ASCII is a 7-bit character set. '¤' is part of Unicode (and Latin-1). Unicode calls it "CURRENCY SIGN". It's not a replacement for '$' (DOLLAR SIGN), which still exists in ASCII, Latin-1, and Unicode. (DOLLAR SIGN is 0x24. CURRENCY SIGN is 0xA4.) If there's a political issue, it's not one that interests me unless it's relevant to C++. -- 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 */ |
James Kuyper <jameskuyper@alumni.caltech.edu>: Aug 21 11:21PM -0400 On 8/21/19 10:24 PM, Keith Thompson wrote: > "Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com> writes: ... > believe has not changed since 1967. Do you have a citation for that? > '$' is not in the source or execution basic character set, a decision > that was made a long time ago. To be more precise, that decision predates the C++ standard, which inherited it from the C standard. It had already been made by the time C89 was approved. K&R did not allow '$' in identifiers, and didn't use it anywhere in the C grammar, but didn't say anything about whether an implementation was required to accept such characters if they appeared in header names, comments, character constants, or string literals. The decision to not include $ in either the source or execution basic character sets was presumably made at the same time that it was decided that the standard should specify those sets. |
"Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com>: Aug 22 06:01AM +0200 On 22.08.2019 04:24, Keith Thompson wrote: >> execution character set. > I've never heard of any attempt to remove '$' from ASCII, which I > believe has not changed since 1967. Do you have a citation for that? Wikipedia's article on `¤` mentions that the replacement was formally proposed by Italy. It cites an article on the web, written by an unknown *nix administrator in the 1990s, but with easily checkable facts: <url: http://czyborra.com/charsets/iso646.html> [quote] ASCII and its national variants were declared international standard ISO 646 in 1972. Back then, the socialist countries managed to substitute the international currency sign ¤ for ASCII's capitalist dollar sign $ in the the first international reference version ISO-646-IRV but this was revised in 1991 and now ISO-646-IRV is a synonym for ISO-646-US or US-ASCII as it is used in the core Internet protocols. [/quote] I guess this is where I remembered Russia from. Or some other source discussing the same history. It was all political. The 1991 6th edition of that standard confirms in its annex C the above claim that the new ASCII, ISO-646 (note: the codes of Unicode are ISO-10646), "was revised" back to its former `$`-glory: [quote] 3) In the G0 set of the IRV the character DOLLAR SIGN replaces the character CURRENCY SIGN in position 2/4. Otherwise this G0 set is unchanged. [quote] >> that. It's meaningless except as a political statement, but it's there >> on my keyboard, taking up one key combination. > There is no "new ASCII". I'm sorry, that's just wrong, although that statement is literally true by using the word "is" instead of "never was". > of Unicode (and Latin-1). Unicode calls it "CURRENCY SIGN". It's not a > replacement for '$' (DOLLAR SIGN), which still exists in ASCII, Latin-1, > and Unicode. (DOLLAR SIGN is 0x24. CURRENCY SIGN is 0xA4.) Yes, it's back in place. Since 1991. Apparently the international currency sign idiocy was adopted in 1972, but even Wikipedia contradicts itself on this matter, so I'm not 100% sure when it started. > If there's > a political issue, it's not one that interests me unless it's relevant > to C++. I think it's quite possibly relevant to the original decision to not include `$`. A mistaken political correctness stance where `$` was seen as just too Western-ish, as a kind of discrimination. Cheers!, - Alf |
James Kuyper <jameskuyper@alumni.caltech.edu>: Aug 22 12:26AM -0400 On 8/22/19 12:01 AM, Alf P. Steinbach wrote: > On 22.08.2019 04:24, Keith Thompson wrote: >> "Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com> writes: ... >> There is no "new ASCII". > I'm sorry, that's just wrong, although that statement is literally true > by using the word "is" instead of "never was". ASCII was first standardized as ASA X3.4-1963, and was revised in 1965, 1967, 1968, 1977, and 6 different versions came out in 1986 <https://en.wikipedia.org/wiki/ASCII#History>. So you're right - there has been a "new ASCII" - a total of 10 of them, in fact. However, that was all a long time ago, and every one of those versions included $. What you're referring to is an early version of ISO/IEC 646, which was based on ASCII and was ASCII's successor, but is not, itself, ASCII. |
"Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com>: Aug 22 07:54AM +0200 On 22.08.2019 06:26, James Kuyper wrote: > 1967, 1968, 1977, and 6 different versions came out in 1986 > <https://en.wikipedia.org/wiki/ASCII#History>. So you're right - there > has been a "new ASCII" - a total of 10 of them, in fact. You're talking about the US national variant of ISO-646. That's a meaningless interpretation of what I wrote. What the fuck could I have meant when I wrote "the new ASCII that I don't remember the name of"? Could it be that I didn't remember the name ASCII that I mentioned in that very sentence? Yes, that must surely have been what I meant. But wait, that's already clarified up-thread, in the parts you snipped: it was ISO 646, the international, ISO version of ASCII. Removing significant context and introducing one's own apparent context instead, is not like debate or clarification. That's instead a common trolling technique. > However, that > was all a long time ago, and every one of those versions included $. Yes, and as you well know that's irrelevant to anything in this thread. Perhaps there were reasons that caused you to not see as relevant the stuff that you snipped, but a debate or clarification can't be your goal because you can't be unaware of the facts: you're presenting some. The stuff that you snipped included reference to ISO 646, the international version of ASCII, which from (apparently) 1972 to (verified) 1991 had the `$` replaced with an unusable international currency symbol `¤`. > What you're referring to is an early version of ISO/IEC 646, which was > based on ASCII and was ASCII's successor, but is not, itself, ASCII. Yes, and again, as you well know that's irrelevant to anything. Not sure if I should plink you, you're not usually trolling this way, - Alf |
James Kuyper <jameskuyper@alumni.caltech.edu>: Aug 22 09:08AM -0400 On 8/22/19 1:54 AM, Alf P. Steinbach wrote: >> <https://en.wikipedia.org/wiki/ASCII#History>. So you're right - there >> has been a "new ASCII" - a total of 10 of them, in fact. > You're talking about the US national variant of ISO-646. No, ASCII and ISO-646 have been developed cooperatively, and there is a US national variant of ISO-646 that is identical in content to one of the versions of ASCII, but that doesn't make ASCII a national variant of ISO-646. > What the fuck could I have meant when I wrote "the new ASCII that I > don't remember the name of"? Could it be that I didn't remember the name > ASCII that I mentioned in that very sentence? No, each version of ASCII had it's own name, such as ASA X3/4-1963 and ANSI-INCITS 4-1986. It was quite clear, since you describe it as having replaced the dollar sign with the currency symbol, that the only thing you could have been referring to was ISO 646 IRV. However, given your usual sloppiness of thought, I assumed that you actually meant what you said - that you were under the impression that ISO 646 IRV was the name of a "... new [version of] ASCII ..." but that you couldn't remember the name of that particular version. I'm glad to hear that this was only sloppy wording on your part, and that you're actually aware that it's a different standard, issued by an international standards organization, rather than a merely national one. |
scott@slp53.sl.home (Scott Lurndal): Aug 22 01:17PM >> allow compilers to accept $ in identifiers. >> [...] >Yes, I should have written MPE/IV, the OS we used on the HP3000. Sorry. Which HP3000 language allowed '$' in identifiers? On most HP3000 compilers the $ was used in column 1 to introduce compiler control commands, for example in SPL/3000: $TITLE "SON OF OVERLORD (SOO)" $CONTROL USLINIT,NOWARN,MAP,CODE $CONTROL SEGMENT=SOO BEGIN ... SPL did allow apostrophes in identifiers: INTEGER PRIORITY, XDS'SUB, MAXPCB', MODE; The engineers that designed the HP3000 were mostly ex-burroughs engineers, which is where the use of $ as a compiler control originated. >It's possible that all this is tied to the attempt to remove `$` in >ASCII, as I recall instigated by Russia or France, a political thing. C'est what? > I >mean, tied by the baffling decision to not include `$` in the C++ basic >execution character set. Maybe because the '$' symbol was often substited with a national symbol (e.g. the british pound symbol); it wasn't a fixed glyph worldwide. |
David Brown <david.brown@hesbynett.no>: Aug 22 04:07PM +0200 On 22/08/2019 15:17, Scott Lurndal wrote: > Maybe because the '$' symbol was often substited with a national > symbol (e.g. the british pound symbol); it wasn't a fixed glyph > worldwide. It was the # symbol that was replaced by £ in the GB version of ISO-646, and on British keyboards. The $ sign remained. (Also ~ was replaced by an overbar ‾, but I've no idea why.) The $ symbol was kept in most, but not all, ISO-646 character sets. It was more common to replace characters like # { } [ ] | and ~ , all of which are still there in C (but have trigraphs). On a related topic, what is the rationale behind the choice of characters allowed in universal character identifiers? There seems to be a vague attempt to allow "letters" but not "symbols". Surely allowing symbols like ¤ £ and § would be ideal for the kind of thing Alf has in his library - characters that would not conflict with anything else, stand out clearly, and can by typed easily on many keyboard layouts (even with Windows). Perhaps € would be a good choice - it is in the list of allowed Unicode identifier characters. |
"Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com>: Aug 22 07:37PM +0200 On 22.08.2019 15:08, James Kuyper wrote: >> ASCII that I mentioned in that very sentence? > No, each version of ASCII had it's own name, such as > ASA X3/4-1963 and ANSI-INCITS 4-1986. "It's" is spelled "its". That's pretty sloppy spelling from you. > [snip] > However, given your usual sloppiness of thought, You don't say. > actually meant what you said - that you were under the impression that > ISO 646 IRV was the name of a "... new [version of] ASCII ..." but that > you couldn't remember the name of that particular version. That explanation does not address the precision of snipping all mention of ISO 646 in the text your replied to, which appeared to be designed to mislead. Not addressing your snipping of significant context is a sloppiness of deception, an art that you don't quite master. > I'm glad to hear that this was only sloppy wording on your part, And that's associative, like an associative mind. It's true that the wording was intentionally imprecise. It communicated exactly what I meant to say, notwithstanding your unconvincing attempt to put it in a different context, remove all mention of what it meant, and so on. > and > that you're actually aware that it's a different standard, issued by an > international standards organization, rather than a merely national one. You didn't learn that now. You snipped those parts of the quoted text, remember. To do that snipping you had to recognize what it was about, which you now pretend to have understood, which means you are now conveying an incorrect impression that you /know/ is incorrect, which there is a word for. Cheers!, - Alf |
Szyk Cech <szykcech@spoko.pl>: Aug 22 06:18PM +0200 Hello! I want follow advises of great book: "Testen in Scrum-Projekten" by Tilo Linz. One of his advises which I consider easy to make is use static code analyser to check if programmers respect coding rules. I am looking for C++ code analyser but I am interested with such tool for Java Script or Bash also. I found great wiki page with list of most popular static code analysers: https://en.wikipedia.org/wiki/List_of_tools_for_static_code_analysis but I have no time to try all of them. So maybe you have some experience with those tools if so: Please answer me to question: What is easiest to use static C++ code analyser? Thak you in advance and best regards! Szyk Cech |
JiiPee <no@notvalid.com>: Aug 22 03:25PM +0100 On 21/08/2019 20:52, Öö Tiib wrote: > Snipping possible misrepresentation of Herb Sutter and > CppCoreGuidelines of isocpp. Sutter says like: "Always make all data members private. The only exception is c-style struct where all members are public" So he was against putting some private and some public. And he proves his point. So according to him if Person class has some functions (like increasing the age automatically) then the age itself should be private and if its value is needed we need a getter. |
"Öö Tiib" <ootiib@hot.ee>: Aug 22 09:06AM -0700 On Thursday, 22 August 2019 17:25:24 UTC+3, JiiPee wrote: > > CppCoreGuidelines of isocpp. > Sutter says like: "Always make all data members private. The only > exception is c-style struct where all members are public" CppCoreGuidelines at <https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#Rh-get> does not conflict with it just suggest to prefer that c-style struct to all trivial setters and getters. That is why your claim seemed misrepresentation. > So he was against putting some private and some public. And he proves > his point. Your OP did not discuss putting some data members private and some public, both are against it: <https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#c134-ensure-all-non-const-data-members-have-the-same-access-level> > So according to him if Person class has some functions (like increasing > the age automatically) then the age itself should be private and if its > value is needed we need a getter. What you seemingly asked in your OP was if to have trivial setters and getters or to have c-style struct. "Getter" is red herring since you don't need one with c-style struct. |
stdcerr <ron.eggler@gmail.com>: Aug 21 08:12PM -0700 On Tuesday, August 20, 2019 at 5:07:52 PM UTC-7, Sam wrote: > > foo(const QSettings *set=0, const QString s="") : > > name(s),settings(set){} > You must be using an obsolete C++ book. I used the really thick book called Internet only and it didn't say that it's out-dated syntax, Thanks for correcting this, though! Modern C++ uses uniform > initialization syntax, which would be: > foo(const QSettings *set=0, const QString s="") : name{s},settings{set}{} That looks more like the Lambda syntax from >=C++11 > Basically {} instead of (). This resolves some syntax ambiguities in other > situations (not this particular one, but others, and it's better to remain > consistent). 100% Agreed! Thanks for the correction! > > ^ > > Makefile:471: recipe for target 'foo.o' failed > > make: *** [foo.o] Error 1 I'm not sure why the compiler doesn't like is, why can't the instance of foo not be a pointer? To get past this, I changed it to look like: foo inst = foo(sttngs, QString("quux")); inst.qux(); > const QSettings * const settings; > Which is a const class member named "settings" which is a pointer to a const > QSettings object. The latter one is what I went with as it seems to be more consistent with my requirement. So my constructor prototype now looks like: foo(const QSettings* const set=nullptr, const QString s="") : name{s},settings{set}{} which works fine but now the compiler complains: foo.cpp: In member function 'void foo::qux()': foo.cpp:18:30: error: passing 'const QSettings' as 'this' argument discards qualifiers [-fpermissive] settings->beginGroup(name); ^ In file included from /usr/include/x86_64-linux-gnu/qt5/QtCore/QSettings:1:0, from foo.cpp:2: /usr/include/x86_64-linux-gnu/qt5/QtCore/qsettings.h:130:10: note: in call to 'void QSettings::beginGroup(const QString&)' void beginGroup(const QString &prefix); ^ foo.cpp:22:24: error: passing 'const QSettings' as 'this' argument discards qualifiers [-fpermissive] settings->endGroup(); ^ In file included from /usr/include/x86_64-linux-gnu/qt5/QtCore/QSettings:1:0, from foo.cpp:2: /usr/include/x86_64-linux-gnu/qt5/QtCore/qsettings.h:131:10: note: in call to 'void QSettings::endGroup()' void endGroup(); ^ Makefile:471: recipe for target 'foo.o' failed make: *** [foo.o] Error 1 Does this mean beginGroup() and endGroup() cannot be invoked on a const QSettings pointer ? qux() hasn't changed and still looks like: void foo::qux(void) { QString name = nme_get(); settings->beginGroup(name); /* * ... */ settings->endGroup(); } and nme_get() QString nme_get() {return name;} in order to address the above error, I tried: void foo::qux(void) { QSettings *test = settings; QString name = nme_get(); test->beginGroup(name); /* * ... */ test->endGroup(); } |
James Kuyper <jameskuyper@alumni.caltech.edu>: Aug 21 11:52PM -0400 On 8/21/19 11:12 PM, stdcerr wrote: >>> public: >>> foo(const QSettings *set=0, const QString s="") : >>> name(s),settings(set){} ... >>> Makefile:471: recipe for target 'foo.o' failed >>> make: *** [foo.o] Error 1 > I'm not sure why the compiler doesn't like is, why can't the instance of foo not be a pointer? ... An instance of foo has class type. An class type is, by definition, not a pointer type. You could have defined an implicit conversion from an object of type foo to a pointer to a foo object, but that's almost certainly not what you wanted. > ... To get past this, I changed it to look like: > foo inst = foo(sttngs, QString("quux")); Note: the line above is equivalent to foo inst(sttngs, QString("quux")); >> const QSettings * const settings; >> Which is a const class member named "settings" which is a pointer to a const >> QSettings object. Let me review your options: const QSettings * const settings; Declares settings to be a pointer, which cannot be changed, to a QSettings object that cannot be changed through that pointer. QSettings * const settings; Declares settings to be a pointer, which cannot be changed, to a QSettings object that can be changed through that pointer. const QSettings * settings; Declares settings to be a pointer, which can be changed, to a QSettings object that cannot be changed through that pointer. QSettings * settings; Declares settings to be a pointer, which can be changed, to a QSettings object that can be changed through that pointer. So, which of these declarations is most appropriate for your application? Your code never changes the value of settings once it has been initialized, so declaring settings itself const makes sense. However: ... > foo.cpp: In member function 'void foo::qux()': > foo.cpp:18:30: error: passing 'const QSettings' as 'this' argument discards qualifiers [-fpermissive] > settings->beginGroup(name); <https://doc.qt.io/qt-5/qsettings.html#beginGroup> does not include the 'const' keyword in the declaration for beginGroup(), which is easy to understand, since it describes the behavior as "Appends prefix to the current group.", an action that requires modification of the QSettings object. Therefore, since you call settings->beginGroup(), it does NOT make sense to declare "settings" as a pointer that cannot be used to modify the object it points at. What you want is QSetting * const settings; > Does this mean beginGroup() and endGroup() cannot be invoked on a const QSettings pointer ? Yes. |
stdcerr <ron.eggler@gmail.com>: Aug 21 08:55PM -0700 On Tuesday, August 20, 2019 at 5:07:52 PM UTC-7, Sam wrote: > > foo(const QSettings *set=0, const QString s="") : > > name(s),settings(set){} > You must be using an obsolete C++ book. I'm mostly using the Internet to find out things now, I've been writing C for many years and know a little about C++(obviously not much/enough) - any good book you would recommend? Modern C++ uses uniform > Basically {} instead of (). This resolves some syntax ambiguities in other > situations (not this particular one, but others, and it's better to remain > consistent). Okay, looks a bit like Lambda in C++11... Yes, I'm all for consistency, too! Thanks! > > 'QSettings*'" > Because your parameter to the constructor is a 'const QSettings *', and your > const class member is a pointer to a non-const QSettings. DUH! Yep, obviously needs to be the same! > const QSettings * const settings; > Which is a const class member named "settings" which is a pointer to a const > QSettings object. Okay, I guess I want a const pointer to a const Object, hence I'll go with: const QSettings * const settings; But I still have issues, my code now looks like: class foo { Q_OBJECT public: foo(const QSettings* const set=nullptr, const QString s="") : name{s},settings{set}{} QString nme_get() {return name;} void qux(void); private: const QString name; const QSettings * const settings; }; void foo::qux(void) { QSettings *test = settings; QString name = nme_get(); test->beginGroup(name); /* * ... */ test->endGroup(); } int main (void) { const QSettings *sttngs = new QSettings(QSettings::NativeFormat,QSettings::UserScope,"GNU","scaper",nullptr ); foo inst = foo(sttngs, QString("quux")); inst.qux(); return 0; } but g++ still tells me: foo.cpp: In member function 'void foo::qux()': foo.cpp:17:23: error: invalid conversion from 'const QSettings*' to 'QSettings*' [-fpermissive] QSettings *test = settings; ^ Makefile:471: recipe for target 'foo.o' failed make: *** [foo.o] Error 1 |
Sam <sam@email-scan.com>: Aug 22 08:40AM -0400 stdcerr writes: > I'm mostly using the Internet to find out things now, I've been writing C > for many years and know a little about C++(obviously not much/enough) - any > good book you would recommend? There's a good list here: https://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list > ^ > Makefile:471: recipe for target 'foo.o' failed > make: *** [foo.o] Error 1 It is true that C++ compilers have a rich reputation for incomprehensible, undecipherable error messages, but this is not one of them, it's as clear as it can be. Of course, you do need to already understand some C++ fundamentals, such as what it means to be a const, and that a pointer to const cannot be converted to a pointer to a non-const object, which is what the error message states. settings is a "const QSettings *", a pointer to a constant QSettings object. You are trying to assign it to a pointer to "QSettings *". That's it. No big mystery. Verbotten. Nyet. Nada. No way. Nein. You /can/ assign a "QSetting *" to a "const QSetting *", basically promising to never modify anything that the "const QSetting *" points to. But once you made that promise it's a one way street. It's true that you might still have the original "QSettings *" somewhere. But as far as the promise made about the new "const QSettings *", it is etched in stone, and irrevocable. So that means that you can't make a "QSettings *" out of it, again. Perhaps you want to grab one of those C++ books, which should explain all of this, and all the rest of your compilation errors will suddenly make sense to me. That might be a more efficient way to get this done. |
Jorgen Grahn <grahn+nntp@snipabacken.se>: Aug 22 02:44PM On Thu, 2019-08-22, stdcerr wrote: > On Tuesday, August 20, 2019 at 5:07:52 PM UTC-7, Sam wrote: ... > I'm mostly using the Internet to find out things now, I've been > writing C for many years and know a little about C++(obviously not > much/enough) - any good book you would recommend? I think you do need a book, for the bigger picture at least. Stroustrup: The C++ Programming Language. The edition that covers C++11. Disclaimers: - Don't know if there's a C++17 edition or whatever on the way. I use the C++11 book and use online sources for the relatively smaller changes after 2011. For the standard library details I almost always go online. - Other recent books may be good. /Jorgen -- // Jorgen Grahn <grahn@ Oo o. . . \X/ snipabacken.se> O o . |
Tim Rentsch <tr.17687@z991.linuxsc.com>: Aug 22 04:47AM -0700 > g++ -c *.o > ld -o prog *.o > [...] Forgive me if this is a dumb question. Is there some reason you have to use gcc in the first step? How about doing this instead: g++ -x c -c *.c g++ -x c++ -c *.cpp g++ -o prog *.o Substituting clang for g++ should also work here. Disclaimer: I haven't verified anything beyond confirming that both g++ and clang accept the -x c and -x c++ options. |
gazelle@shell.xmission.com (Kenny McCormack): Aug 22 12:12PM In article <864l29ifqm.fsf@mailhub.linuxsc.com>, Tim Rentsch <tr.17687@z991.linuxsc.com> wrote: ... >Substituting clang for g++ should also work here. Disclaimer: I >haven't verified anything beyond confirming that both g++ and >clang accept the -x c and -x c++ options. I didn't even think you needed the -x option, as long as your files have recognized extensions. For example, when compiling normal C code, your files have extenion ".c" and you don't need any "-x c" option. You only need "-x" if you need to override the default *or* you're in a situation where gcc can't figure out what type of file it is (e.g., you are reading the program text from stdin). There is a list somewhere of the recognized extentions and which language they are associated with. -- When someone tells me he/she is a Christian I check to see if I'm still in posession of my wallet. |
David Brown <david.brown@hesbynett.no>: Aug 22 03:08PM +0200 On 22/08/2019 14:12, Kenny McCormack wrote: > need "-x" if you need to override the default *or* you're in a situation > where gcc can't figure out what type of file it is (e.g., you are reading > the program text from stdin). "gcc file" will compile "file.c" as C, and "file.cpp" as C++. But "g++ file.c" will compile the file as C++ rather than c. (I'm not asking anyone to like this, I just saying the way it works.) The "-x" switch lets you override the language choices of "gcc" or "g++". However you choose to invoke gcc, I'd also recommend you explicitly choose the standard you want - "-std=gnu++17", "-std=c++14", or whatever suits your needs. The default here has changed before, and will change again in the future. > There is a list somewhere of the recognized extentions and which language > they are associated with. <https://gcc.gnu.org/onlinedocs/gcc/Invoking-G_002b_002b.html> <https://gcc.gnu.org/onlinedocs/gcc/Overall-Options.html> |
Tim Rentsch <tr.17687@z991.linuxsc.com>: Aug 22 05:05AM -0700 > ... valid? > I'd guess that it's not valid as C++11, but possibly valid as > C++14 or later. fwiw, g++ and clang accept it without complaint under -std=c++14 and -std=c++17, but give a diagnostic under -std=c++11. That result holds both with and without a -pedantic option. |
David Brown <david.brown@hesbynett.no>: Aug 22 01:30PM +0200 On 21/08/2019 21:39, Chris Vine wrote: > generates randomly incorrect results and gives rise to a race condition > in common parlance. > It is important to be clear which case you are in fact referring to. That's some good points. It is /relatively/ easy tell if you have no data races in your code even if you are not strict about using C++11/C11 atomics or implementation-specific atomics. If your code does not access potentially shared objects that are bigger than the hardware's write size, and it only uses reads or writes to them (it doesn't assume that "x += 1;" is atomic), then you are not going to get data races. When two 32-bit cores both try to write to the same 32-bit memory address, one core will hit first - you are not going to get a mixed write unless you have a rather unusual and specialised system. You might have noticed quite a few if's there - you have to be quite restricted in your code to avoid the possibility of data races (as defined by the C++ standard). And without additional guarantees from your hardware, such as a total ordering on volatile accesses, it is not going to be enough to be useful. If your system is relatively simple - like a single core microcontroller - then you /do/ have such guarantees, and "volatile" can be enough. For the OP, however, he doesn't have such hardware - and "volatile" is not going to cut it. Proving that you don't have any more general "race conditions" or improper synchronisation is a lot harder. > is atomic at the hardware level, such as an int, has identical effect > to using the equivalent atomic variable with relaxed memory ordering. > The code emitted by the compiler is identical. Agreed. I can imagine machines for which that is not the case - perhaps using caches which do not snoop between other cpus' caches. This would make some aspects of programming significantly harder, but could make hardware a lot simpler (and therefore faster and/or cheaper). I'd expect to see it only in quite specialised systems. > code unnecessarily" seems to me to be a reasonable answer, provided the > program is indeed adequately synchronized by some other means such as > fences, so that it does not contain a race condition in common parlance. Volatile accesses have certain advantages over atomics - even relaxed atomics. Let us restrict ourselves to the world of single-core systems, as is typical for microcontrollers - since when you have multi-core systems you will be needing atomics and locks (correctness trumps efficiency and convenience every time, and we know volatile is not enough for most purposes in such systems). We'll assume a 32-bit system for convenience. Such systems are often asymmetric in their threading. You have a hierarchy. If you have a RTOS, you have a layers of threads that have strictly controlled priorities. A higher priority thread can pre-empt a lower priority thread, but not vice versa - but complicated by priority boosting at times. Above that, you have layers of interrupts at different priorities, usually more strictly prioritised. Imagine a timer interrupt function that tracks time as a 64-bit counter. The "global_timer" variable is only ever written within that interrupt function. It can be declared "int64_t global_timer;", and incremented as "global_timer++;". This is safe - no need for atomics, volatile, or anything else - these would be pessimisations. For code that reads this value from another thread or context, you need to be smarter. Here you /do/ need volatile accesses. #define volatileAccess(v) *((volatile typeof((v)) *) &(v)) (Forgive the gcc'ism and C style - in C++, you'd make a template but it doesn't affect the principle.) You can read your global timer in various ways, such as: disable_interrupts(); int64_t now = volatileAccess(global_timer); enable_interrupts(); or int64_t now = volatileAccess(global_timer); int64_t now2 = volatileAccess(global_timer); while (now != now2) { now = now2; now2 = volatileAccess(global_timer); } (You can also break this last one into separate high and low words to be slightly more efficient.) Both of these are much more efficient than using relaxed 64-bit atomic access, as such accesses are often implemented. Even more importantly, both of them /work/ - unlike some implementations I have seen of atomic accesses (like <https://gcc.gnu.org/wiki/Atomic/GCCMM?action=AttachFile&do=view&target=libatomic.c>) which rely on spinlocks. A key point here with volatiles is that you can have a normal object, and use volatile accesses on it. You can't do that with atomic objects, in the way you can with the macro above, limiting your flexibility to use your knowledge of the program to use different access types for different balances of efficiency and synchronisation control. It's true that a relaxed atomic load or store is going to be efficient for small enough sizes - and the cost is just the ugly and verbose syntax. For larger sizes, it's a different matter. If your code is within a critical section (due to a lock, or interrupt control) and you know it cannot possibly clash with other access to the same object, there is a huge efficiency difference between using a normal access to the object, and using an atomic access (even a relaxed one). |
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