- Don't be fooled by cpp.sh - 8 Updates
- Two silly problems - 3 Updates
- I'd like to have unusing - 6 Updates
boltar@nowhere.org: Dec 26 09:46AM On Wed, 25 Dec 2019 00:30:46 +0200 >"If an optional<T> contains a value, the value is guaranteed to be >allocated as part of the optional object footprint, i.e. no dynamic >memory allocation ever takes place. Thus, an optional object models an Of course dynamic memory allocation takes place - its not going to be on the stack if its in a container is it? It might be implicit rather than explicit but its still dynamic and as such is subject to where the allocator puts it. |
Paavo Helde <myfirstname@osa.pri.ee>: Dec 26 04:38PM +0200 >> memory allocation ever takes place. Thus, an optional object models an > Of course dynamic memory allocation takes place - its not going to be on > the stack if its in a container is it? If a std::optional is stored as an automatic variable then of course it is allocated at stack. Where else? And this includes also its contained value, as there is absolutely no reason to allocate it dynamically. > It might be implicit rather than > explicit but its still dynamic and as such is subject to where the allocator > puts it. Fortunately programming is a concrete field and one can answer concrete enough questions factually, no need to decide anything be shouting louder than others. Here is a little program to find out where a class A value contained in a std::optional is allocated. You can run it with your favorite C++ compiler if you don't trust mine. #include <optional> #include <iostream> class A { public: A(int a) : a_(a) {} void foo() const { std::cout << "Hello, I'm an A at address: " << this << "\n"; } private: int a_; }; int main() { int x = 1; std::optional opt1 = A(42); int y = 2; std::cout << "Stack variable x is at address: " << &x << "\n"; std::cout << "Stack variable y is at address: " << &y << "\n"; opt1->foo(); } Output: Stack variable x is at address: 00000000002CF874 Stack variable y is at address: 00000000002CF8B4 Hello, I'm an A at address: 00000000002CF898 So, what's next? Will you claim that x and y are not stack variables? Or will you deny 0x2CF898 lies between 0x2CF874 and 0x2CF8B4? Or will you say that the dynamic allocator somehow is able to use memory space between two stack variables for a dynamic allocation? Or will you say that all existing implementations of std::optional are wrong in storing the value on stack and should use the more expensive dynamic allocation instead? Note that if the value contained in a std::optional would be indeed allocated dynamically, there would be no need for std::optional in the first place as then one would have a (raw or smart) pointer pointing to this dynamically allocated value, and one could just use the special nullptr value for indicating the "missing value" condition. |
boltar@nowhere.org: Dec 26 05:33PM On Thu, 26 Dec 2019 16:38:12 +0200 >If a std::optional is stored as an automatic variable then of course it >is allocated at stack. Where else? And this includes also its contained >value, as there is absolutely no reason to allocate it dynamically. For some noddy function. If however you have a container that is added to based on some operation in a loop its hardly going to be allocated on the stack is it? (Unless you use an allocator that uses alloca() or similar. And good luck with that). >value contained in a std::optional is allocated. You can run it with >your favorite C++ compiler if you don't trust mine. A contrived example. Now allocate optionals containing objects in a loop. |
Paavo Helde <myfirstname@osa.pri.ee>: Dec 26 07:52PM +0200 > based on some operation in a loop its hardly going to be allocated on the > stack is it? (Unless you use an allocator that uses alloca() or similar. And > good luck with that). True for some kind of containers, but std::optional is not one of those. >> value contained in a std::optional is allocated. You can run it with >> your favorite C++ compiler if you don't trust mine. > A contrived example. Now allocate optionals containing objects in a loop. You cannot refute direct evidence just be calling it "contrived" (which it isn't). And loops have nothing to do with how std::optional works. |
Mr Flibble <flibble@i42.removethisbit.co.uk>: Dec 26 06:30PM >> value contained in a std::optional is allocated. You can run it with >> your favorite C++ compiler if you don't trust mine. > A contrived example. Now allocate optionals containing objects in a loop. #include <optional> #include <iostream> int main() { std::optional<int> o = 42; std::cout << "address of optional on stack: " << std::hex << &o << std::endl; std::cout << "address of optional contained value: " << std::hex << &*o << std::endl; } Output: address of optional on stack: 0x7ffc35b03890 address of optional contained value: 0x7ffc35b03890 Now will you please fuck off you deliberately obtuse idiot. /Flibble -- "You won't burn in hell. But be nice anyway." – Ricky Gervais "I see Atheists are fighting and killing each other again, over who doesn't believe in any God the most. Oh, no..wait.. that never happens." – Ricky Gervais "Suppose it's all true, and you walk up to the pearly gates, and are confronted by God," Bryne asked on his show The Meaning of Life. "What will Stephen Fry say to him, her, or it?" "I'd say, bone cancer in children? What's that about?" Fry replied. "How dare you? How dare you create a world to which there is such misery that is not our fault. It's not right, it's utterly, utterly evil." "Why should I respect a capricious, mean-minded, stupid God who creates a world that is so full of injustice and pain. That's what I would say." |
Daniel <danielaparker@gmail.com>: Dec 26 10:38AM -0800 > the stack if its in a container is it? It might be implicit rather than > explicit but its still dynamic and as such is subject to where the allocator > puts it. A typical implementation of optional<T> uses data storage something like union { char dummy; std::remove_const_t<T> value; }; bool has_value; and uses placement new to initialize value if defined. There's no dynamic allocation happening here, for example, std::optional<std::string> o1{}; // does not contain a value std::optional<std::string> o2 = "Hello"; // contains a small string value Best regards, Daniel |
Keith Thompson <Keith.S.Thompson+u@gmail.com>: Dec 26 10:54AM -0800 > On 26.12.2019 11:46, boltar@nowhere.org wrote: [...] > it is allocated at stack. Where else? And this includes also its > contained value, as there is absolutely no reason to allocate it > dynamically. [...] > shouting louder than others. Here is a little program to find out > where a class A value contained in a std::optional is allocated. You > can run it with your favorite C++ compiler if you don't trust mine. [...] Your program only demonstrates that the T object is allocated within the optional<T> object *for the implementation you used*. (Defining an optional<T> type with a large parameter type T and printing its size would be a simpler way to demonstrate that.) I can easily imagine that a different implementation might store the T object outside the optional<T> object, saving space when it's not present. What *does* prove that the T object is stored within the optional<T> object is that the standard says it must be. C++17 23.6.3 [optional.optional] paragraph 1: Any instance of optional<T> at any given time either contains a value or does not contain a value. When an instance of optional<T> *contains a value*, it means that an object of type T, referred to as the optional object's contained value, is allocated within the storage of the optional object. Implementations are not permitted to use additional storage, such as dynamic memory, to allocate its contained value. -- Keith Thompson (The_Other_Keith) Keith.S.Thompson+u@gmail.com [Note updated email address] Working, but not speaking, for Philips Healthcare void Void(void) { Void(); } /* The recursive call of the void */ |
Paavo Helde <myfirstname@osa.pri.ee>: Dec 26 10:50PM +0200 On 26.12.2019 20:54, Keith Thompson wrote: > What *does* prove that the T object is stored within the optional<T> > object is that the standard says it must be. C++17 23.6.3 > [optional.optional] paragraph 1: You are right, but as it appears "boltar" is not easily swayed by mere words, I was trying something more concrete. Probably in vain... |
"Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com>: Dec 26 04:47PM +0100 Why, with the below code, do I get this result: > echo no no no not ever | a ever 1 no 1 not 1 I had expected a count of three for "no". Also, how the feck does the commented line cause a Most Vexing Parse? I was sure that by having a constructor call with `cin` as argument there, i.e. a value argument, there could be no vexing parse. But g++ just doesn't like it and then misleadingly complains about something later in the code, using an avalanche of idiot diagnostics so as to ensure one would waste time on it. ------------------------------------------------- // Read a file of text, determine the n most frequently used words, and print out a sorted // list of those words along with their frequencies. // // https://medium.com/@vgasparyan1995/a-little-bit-of-code-c-20-ranges-c6a6f7eae401 // Assuming // * ASCII lowercase text // * No punctuation. #include <iterator> #include <iostream> #include <string> #include <unordered_set> template< class Key > using Multiset_ = std::unordered_set<Key>; auto main() -> int { using std::cin, std::cout, std::endl, std::string; using Iit = std::istream_iterator<string>; const Iit end = Iit(); Multiset_<string> words( Iit( cin ), (Iit()) ); // OK //Multiset_<string> words( Iit( cin ), Iit() ); //! Most vexing parse? for( const string& s: words ) { cout << s << ' ' << words.count( s ) << endl; } } ------------------------------------------------- - Alf (possibly in superstupido-mode, for various reasons) |
"Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com>: Dec 26 04:51PM +0100 On 26.12.2019 16:47, Alf P. Steinbach wrote: > no 1 > not 1 > I had expected a count of three for "no". Oh, just a typo. I had forgot to writ "multi" in std::unordered_multiset. > doesn't like it and then misleadingly complains about something later in > the code, using an avalanche of idiot diagnostics so as to ensure one > would waste time on it. But this? I can't get my head around it. Right now. |
Bo Persson <bo@bo-persson.se>: Dec 26 04:55PM +0100 On 2019-12-26 at 16:47, Alf P. Steinbach wrote: > } > ------------------------------------------------- > - Alf (possibly in superstupido-mode, for various reasons) Some more coffee needed, possibly? Multiset_ sounds like a multiset, but it really is not if we read the using-line carefully. :-) And for the most vexing parse - cin is a value, but it *could* also be the name of a parameter for a (hypothetical) words function. So parsing a declaration wins! Bo Persson |
"Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com>: Dec 26 12:49AM +0100 On 25.12.2019 23:28, Pavel wrote: > I make 2 conclusions: > A. some identifiers (in particular those starting with _) shall not be > used by otherwise than by C++ implementation The parenthetical remark does not follow from anything. > B. If an identifier starting with _ not followed by an uppercase letter > is used by C++ implementation, it should be used as a name in the global > namespace. ... or namespace `std`. > clause Alf referred to in his recollection of the Standard, namely: > Identifiers starting with `_` are reserved in the global namespace. > What I am missing? Rather, the question is where you get these ideas. - Alf |
Pavel <pauldontspamtolk@removeyourself.dontspam.yahoo>: Dec 25 07:54PM -0500 Alf P. Steinbach wrote: >> A. some identifiers (in particular those starting with _) shall not be >> used by otherwise than by C++ implementation > The parenthetical remark does not follow from anything. except it follows from 3.2 cited right above >> is used by C++ implementation, it should be used as a name in the global >> namespace. > ... or namespace `std`. *that* is what does not seem to follow from anything. >> Identifiers starting with `_` are reserved in the global namespace. >> What I am missing? > Rather, the question is where you get these ideas. Oh, the answer to this one is simple: boolean logic applied to A and B above. |
"Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com>: Dec 26 03:53AM +0100 On 26.12.2019 01:54, Pavel wrote: >> Rather, the question is where you get these ideas. > Oh, the answer to this one is simple: boolean logic applied to A and B > above. This reminds me strongly of the tortoise's denial arguments in Hofstadter's "Gödel, Escher, Bach: An Eternal Golden Braid". I recommend that book. - Alf |
Pavel <pauldontspamtolk@removeyourself.dontspam.yahoo>: Dec 25 10:32PM -0500 Alf P. Steinbach wrote: > This reminds me strongly of the tortoise's denial arguments in > Hofstadter's "Gödel, Escher, Bach: An Eternal Golden Braid". > I recommend that book. nice try. |
"Öö Tiib" <ootiib@hot.ee>: Dec 26 03:01AM -0800 On Thursday, 26 December 2019 02:55:04 UTC+2, Pavel wrote: > >> (3.2) — Each identifier that begins with an underscore is reserved to > >> the implementation for use as a name in > >> the global namespace. Sometimes I notice hieroglyph fi used instead of fi in normative texts. Like "identifier". Perhaps there is saboteur among the language lawyers that wants to make it harder to search the texts. > >> used by otherwise than by C++ implementation > > The parenthetical remark does not follow from anything. > except it follows from 3.2 cited right above I understand how the sentence may be interpreted like that out of context but that interpretation does not make sense in C++. Names have scope in C++ (or can lack it on case of macros and keywords). So "as names in the global namespace" means that it is where the rule applies. Similarly "for any use" means that such names are reserved for any (scoped or scope-less) usage. Characters of Alice in Wonderland kept constantly misinterpreting meanings of sentences like that so perhaps it is just limitation of human languages. Or can you propose better wording? > >> namespace. > > ... or namespace `std`. > *that* is what does not seem to follow from anything. There standard has chosen to other way of reserving, the menace of undefined behavior when user touches namespace std in wrong way: "The behavior of a C++ program is undefined if it adds declarations or definitions to namespace std or to a namespace within namespace std unless otherwise specified. A program may add a template specialization for any standard library template to namespace std only if the declaration depends on a user-defined type and the specialization meets the standard library requirements for the original template and is not explicitly prohibited." > > Rather, the question is where you get these ideas. > Oh, the answer to this one is simple: boolean logic applied to A and B > above. English does not unfortunately translate into boolean logic. No human language does. |
"Öö Tiib" <ootiib@hot.ee>: Dec 26 03:20AM -0800 On Thursday, 26 December 2019 13:01:25 UTC+2, Öö Tiib wrote: > only if the declaration depends on a user-defined type and the > specialization meets the standard library requirements for the original > template and is not explicitly prohibited." Note that by your interpretation, Pavel, standard is violating itself: <https://en.cppreference.com/w/cpp/utility/functional/placeholders> |
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