- When auto can and can not deduce const - 1 Update
- Zeroing in the constructor - 9 Updates
- Quick simple question: - 2 Updates
- Help on 'delete[] data' in an example - 1 Update
- Quick fun question - 3 Updates
- Zeroing in the constructor - 4 Updates
- A confusing topic in Stroustrup's book - 1 Update
- Confusing passage in C++ book - 2 Updates
- error compiling simple threading example... - 1 Update
- create a class using null type? - 1 Update
Paul <pepstein5@gmail.com>: Jun 13 05:13AM -0700 Below is quoted from a C++ book. I don't understand why the cases auto& g = ci; and auto &h = 42; are different. auto& h = 42; is an error because we can't bind a plain reference to a literal. So why is auto& g = ci; allowed? If auto& h = 42 binds a plain reference to a literal then why doesn't auto& g = ci; bind a plain reference to a const int? Many thanks for your help, Paul BEGIN QUOTE int i = 0, &r = i; auto a = r; // a is an int (r is an alias for i, which has type int) Second, auto ordinarily ignores top-level consts. As usual in initializations, low-level consts, such as when an initializer is a pointer to const, are kept const int ci = i, &cr = ci; auto b = ci; // b is an int (top-level const in ci is dropped) auto c = cr; // c is an int (cr is an alias for ci whose const is top-level) auto d = &i; // d is an int*(& of an int object is int*) auto e = &ci; // e is const int*(& of a const object is low-level const) If we want the deduced type to have a top-level const, we must say so explicitly const auto f = ci; // deduced type of ci is int; f has type const int We can also specify that we want a reference to the auto-deduced type. Normal initialization rules still apply auto &g = ci; // g is a const int& that is bound to ci auto &h = 42; // error: we can't bind a plain reference to a literal const auto &j = 42; // ok: we can bind a const reference to a literal END QUOTE |
legalize+jeeves@mail.xmission.com (Richard): Jun 12 11:03PM [Please do not mail me a copy of your followup] Noob <root@127.0.0.1> spake the secret code >are missing in the constructor, I could just bulldoze the >entire object: > std::memset(this, 0, sizeof *this); Please don't do this. Instead crank up the warning level on your compiler to have it tell you which members are uninitialized. #include <iostream> class A { public: A() : f() {} int get_f() { return f; } int get_g() { return g; } private: int f; int g; }; int main() { A a; std::cout << "f = " << a.get_f() << "\n" << "g = " << a.get_g() << "\n"; } shell 161> g++ -Weffc++ /tmp/a.cpp /tmp/a.cpp: In constructor 'A::A()': /tmp/a.cpp:6:2: warning: 'A::g' should be initialized in the member initialization list [-Weffc++] A() ^ Tools like cppcheck can also identify uninitialized members of a class. <http://cppcheck.sourceforge.net/> -- "The Direct3D Graphics Pipeline" free book <http://tinyurl.com/d3d-pipeline> The Computer Graphics Museum <http://computergraphicsmuseum.org> The Terminals Wiki <http://terminals.classiccmp.org> Legalize Adulthood! (my blog) <http://legalizeadulthood.wordpress.com> |
Ian Collins <ian-news@hotmail.com>: Jun 13 11:30AM +1200 Richard wrote: > shell 161> g++ -Weffc++ /tmp/a.cpp A gcc option that breaks google :) Your search - -Weffc++ - did not match any documents. -- Ian Collins |
Victor Bazarov <v.bazarov@comcast.invalid>: Jun 12 07:56PM -0400 On 6/12/2015 7:39 PM, Stefan Ram wrote: > It only »breaks« the expectations of Google users who did > not study the Google operators manual before using the Google > »-« operator in their Google search specifications. Pfft! Real programmers never read manuals! ;-) V -- I do not respond to top-posted replies, please don't ask |
legalize+jeeves@mail.xmission.com (Richard): Jun 13 12:15AM [Please do not mail me a copy of your followup] Ian Collins <ian-news@hotmail.com> spake the secret code >> shell 161> g++ -Weffc++ /tmp/a.cpp >A gcc option that breaks google :) > Your search - -Weffc++ - did not match any documents. <http://bfy.tw/JZU> -- "The Direct3D Graphics Pipeline" free book <http://tinyurl.com/d3d-pipeline> The Computer Graphics Museum <http://computergraphicsmuseum.org> The Terminals Wiki <http://terminals.classiccmp.org> Legalize Adulthood! (my blog) <http://legalizeadulthood.wordpress.com> |
Noob <root@127.0.0.1>: Jun 13 10:57AM +0200 On 13/06/2015 01:03, Richard wrote: > Please don't do this. > Instead crank up the warning level on your compiler to have it tell you > which members are uninitialized. You don't say why the latter is better? The current constructor is ~60 lines of code. In my (predominantly C) experience, clearing the entire struct with a single line communicates the intent more clearly, which results in less maintenance over time. Are you concerned about complex classes (with virtual inheritance, and perhaps other features)? If we are talking about a plain struct, there are no problems, right? (Although I seem to recall that C++'s "struct" is just a synonym for "class" with everything public.) If the class consists only of int fields + accessors, are there unforeseen drawbacks to zeroing with memset? (Thanks for the -Weffc++ flasg nonetheless) Regards. |
Christian Gollwitzer <auriocus@gmx.de>: Jun 13 11:13AM +0200 Am 12.06.15 um 22:54 schrieb Noob: > is supposed to set everything to 0s and NULLs, but it misses a > few fields, and the program blows up when it uses one of these > uninitialized fields. The best way to debug such things is a memory checker. If you can compile your code on Linux, then valgrind is the best tool you can ever have. It will tell you which fields have been red without prior initialization. Tools for other platforms exist, too. I think Visual C++ has a compiler flag to catch these things. And, if the culprit is really the constructor, even the compiler can issue a warning with the highest warning level. Christian |
Christian Gollwitzer <auriocus@gmx.de>: Jun 13 11:32AM +0200 Am 13.06.15 um 10:57 schrieb Noob: > In my (predominantly C) experience, clearing the entire struct with > a single line communicates the intent more clearly, which results in > less maintenance over time. That's because C doesn't have the concept of initialization at all. You can just assign something. The constructor/destructor pair gives rise to one of the most powerful mechanisms in C++ (RAII) > Are you concerned about complex classes (with virtual inheritance, > and perhaps other features)? Setting the bits to zero discards the type information. The compiler has no way to check that for you. For instance, it is not guaranteed even for a simple float, that all zero bits denotes 0.0 and not some odd value (true for IEEE floats, but...). For real complicated cases this matters, as you say, classes with virtual functions get likely destroyed, because you overwrite the pointer to the VTable. If there are more complex members, like a std::vector, then it is properly constructed by a real constructor. As soon as somebody modifies the class and includes some of these, the code will magically break > (Although I seem to recall that C++'s "struct" is just a synonym for > "class" with everything public.) Yes that is right. If you are worried about the amount of code: How do you currently initialize your variables? Assign them in the body of the constructor? There is a special initialization syntax for constructors: class SomeClass { public: SomeClass() : value(5) {} explicit SomeClass(int new_value) : value(new_value) {} private: int value; }; and in C++11 it is even easier: class SomeClass { public: SomeClass() {} explicit SomeClass(int new_value) : value(new_value) {} private: int value = 5; }; You could do that for all of your fields at the point where they are declared, so would be easy to spot a missing one. Christian |
Marcel Mueller <news.5.maazl@spamgourmet.org>: Jun 13 11:54AM +0200 On 12.06.15 22.54, Noob wrote: > are missing in the constructor, I could just bulldoze the > entire object: > std::memset(this, 0, sizeof *this); This is guaranteed to work if and only if your class is a POD type, i.e. it consists only of built-in data types like int, float, pointer etc. or other POD types in all instance attributes and it neither has a custom constructor nor private or protected instance attributes. > Will this work as expected? Well, in real live on most platforms the condition above is slightly relaxed. I.e. it may also inherit (non-virtual) from a POD type, and neither a custom constructor nor protected attributes cause any harm. To come around the undefined behavior according to the C++ standard you can do a trick: split your class into a POD base type and a non POD derived type. struct myPOD { int SomeInt; AnotherClass* Pointer; //... }; class myPODWrapper : public myPOD { myPODWrapper() { memset(static_cast<myPOD*>(this), 0, sizeof(myPOD)); } }; Now you are perfectly save. You only access the POD base type in a C style manner. (Note the static cast which does the slicing.) The derived type does no longer have any restrictions. It also may have virtual functions and whatever you like. The type myPODWrapper implicitly converts to myPOD and my be flawlessly used for C API calls. The only critical thing are downcasts. They are necessary when a C callback gives you only the POD type pointer. In this case you need to be absolutely sure that you only get the pointers that /you/ passed to the API and not a value copy of the POD slice. I have used this pattern many times to wrap C APIs more safely by simply deriving from their struct types in the C headers. It usually works as long as the API let you allocate the storage for the PODs. Marcel |
Luca Risolia <luca.risolia@linux-projects.org>: Jun 13 01:51PM +0200 Il 12/06/2015 22:54, Noob ha scritto: > is supposed to set everything to 0s and NULLs > std::memset(this, 0, sizeof *this); > Will this work as expected? No, unless you make your classes POD types first. Since you said they define a constructor, they are not POD-classes. To check if a class is a POD type the standard provides std::is_pod<>. |
"K. Frank" <kfrank29.c@gmail.com>: Jun 12 05:43PM -0700 Hi Luca! On Friday, June 12, 2015 at 1:34:45 PM UTC-4, Luca Risolia wrote: > > double res1; > > double res2; > > thread t1 {f,some_vec,&res1}; //f(some_vec,&res1) executes in a separate It seems that you are saying two inconsistent things here -- you first recognize that &res1 is a pointer, but then repeat the mistaken claim that res1 is itself a pointer. > Sorry, typo: it's clear what I meant to say "res" is *a copy* of the > passed pointer which is "&res1" - not "res1", of course. Yes, "the passed pointer" is "&res1". res1 is a double (not a pointer) and &res1 is a pointer (pointer-to-double). > I read your "you don't want to access res1" as if one could not write > res1 (which is a pointer itself), res1 is *not* a pointer. It is a plain double. > which is clearly perfectly safe. Absent synchronization, it is *not* safe to write to res1 (or read from it) in main because thread t1 also has access to res1 through the pointer variable res in t1's thread function, f. When the thread function f runs, res has the value &res1, so f could be writing to res1 (through the pointer), while main is reading from res1. This would undefined behavior. > You > probably meant to say "dereference" instead of "access". No, I meant to say "access" (as in "read to" or "write from"). You cannot dereference res1 because it is not a pointer. To emphasize this point, here is the declaration of res1 from Doug's example code: double res1; res1 is declared to be a double, not a pointer-to-double (nor a pointer to any other type). My original points 1 and 2 stand. Doug's example code is correct because his use of t1.join() provides the necessary thread synchronization, but if the synchronization had not been provided, the code would be incorrect and lead to undefined behavior. t1 has been "granted" access to res1 because it has been passed the value &res1 -- a pointer to res1. 1) If t1 writes to res1 (through the pointer) while main is reading from it, you have an error and undefined behavior. 2) If t1 writes to res1 (through the pointer) after res1 goes out of scope (because main has exited), you have an error and undefined behavior. > is that what you get in f(), when it is invoked in the context of a new > thread of execution, is a const reference to **A COPY** of the original > vector passed as argument to the thread constructor. (I do agree that the thread function gets a copy of the vector some_vec, and that main and t1 can safely access their separate copies of some_vec at the same time without synchronization. In particular, if t1 were to modify its copy of some_vec, those modification would not show up in the original some_vec in main.) Best. K. Frank |
Luca Risolia <luca.risolia@linux-projects.org>: Jun 13 01:01PM +0200 Il 13/06/2015 02:43, K. Frank ha scritto: > res1 is *not* a pointer. It is a plain double. Yes, I kept mixing the types in my mind. I was too tired :) |
Rosario19 <Ros@invalid.invalid>: Jun 13 06:22AM +0200 > int *data; > size_t n; >}; I would say above that "data" is space for a pointer to int, and n is the size of the obj a can point i would say it is + useful something as class array { ... unsigned *d; unsigned dlen; unsigned dsiz; }; "d" is space for a pointer to unsigned int, "dlen" is the number of unsigned elements, obj pointed from"d" contain, dsiz is the number of unsigned "d" can access [the memory "d" can use] for minimize malloc() / free() use |
Victor Bazarov <v.bazarov@comcast.invalid>: Jun 12 11:03PM -0400 On 6/12/2015 10:35 PM, Stefan Ram wrote: > #include <string> > using namespace ::std::literals; > int main() { ::std::cout << "s"s"s"s"s"s << '\n'; } Looks like a syntax error. "s"s is interpreted as a std::string object initialized with one letter 's', and what's the next token? Another literal expression, which also yields an object. In other words, between the << you wrote std::string{"s",1} std::string{"s",1} std::string{"s",1} and no operator between them. That's a syntax error, I think. > ::std::cout << "s""s"s"s" << '\n'; > ::std::cout << "s""s""s" << '\n'; } > Solution: See 2.13.5p13. Solution for what? The "s"s is not a string literal, it's a user-defined literal, to which the paragraph you named does not relate, IMHO. V -- I do not respond to top-posted replies, please don't ask |
Victor Bazarov <v.bazarov@comcast.invalid>: Jun 12 11:07PM -0400 On 6/12/2015 11:03 PM, Victor Bazarov wrote: > Solution for what? The "s"s is not a string literal, it's a > user-defined literal, to which the paragraph you named does not relate, > IMHO. OK, I take it back. User-defined literals are treated as string literals. Which document are you looking at, exactly? I am looking at n4431, which is a draft. V -- I do not respond to top-posted replies, please don't ask |
legalize+jeeves@mail.xmission.com (Richard): Jun 13 03:38AM [Please do not mail me a copy of your followup] Victor Bazarov <v.bazarov@comcast.invalid> spake the secret code >Solution for what? The "s"s is not a string literal, it's a >user-defined literal, to which the paragraph you named does not relate, >IMHO. User-defined string literals participate in string literal concatenation as long as only a single user-defined suffix is used on all the string literals (or no suffix is used on some of the literals). See <http://en.cppreference.com/w/cpp/language/user_literal> just above the heading "Literal Operators". Since C++14, <chrono> defines: constexpr std::chrono::seconds operator""s(unsigned long long s) and <string> defines: constexpr std::string operator""s(const char *str, std::size_t len); constexpr std::u16string operator""s(const char16_t *str, std::size_t len); constexpr std::u32string operator""s(const char32_t *str, std::size_t len); constexpr std::wstring operator""s(const wchar_t *str, std::size_t len); What's kinda cool is that normal operator overloading makes it clear that 54s is std::chrono::seconds and "54"s is a std::string, even when both headers are included in the same source file. -- "The Direct3D Graphics Pipeline" free book <http://tinyurl.com/d3d-pipeline> The Computer Graphics Museum <http://computergraphicsmuseum.org> The Terminals Wiki <http://terminals.classiccmp.org> Legalize Adulthood! (my blog) <http://legalizeadulthood.wordpress.com> |
ram@zedat.fu-berlin.de (Stefan Ram): Jun 12 11:39PM >>shell 161> g++ -Weffc++ /tmp/a.cpp >A gcc option that breaks google :) >Your search - -Weffc++ - did not match any documents. It only »breaks« the expectations of Google users who did not study the Google operators manual before using the Google »-« operator in their Google search specifications. |
ram@zedat.fu-berlin.de (Stefan Ram): Jun 13 02:35AM Quick! What does this print, if anything? #include <iostream> #include <ostream> #include <string> using namespace ::std::literals; int main() { ::std::cout << "s"s"s"s"s"s << '\n'; } Additional question for even more fun: What are the data types of the five expressions between the »<<« in the following program? Or is the program ill formed? #include <iostream> #include <ostream> #include <string> using namespace ::std::literals; int main() { ::std::cout << "s"s"s"s"s" << '\n'; ::std::cout << "s""s"s"s"s << '\n'; ::std::cout << "s""s"s"s" << '\n'; ::std::cout << "s""s"s"s" << '\n'; ::std::cout << "s""s""s" << '\n'; } Solution: See 2.13.5p13. |
ram@zedat.fu-berlin.de (Stefan Ram): Jun 13 03:25AM >Solution for what? The "s"s is not a string literal, it's a >user-defined literal, to which the paragraph you named does not relate, It relates insofar as it might be a place where the meaning of ("a"s"b"s) might be defined. And if it's /not/ defined there, this too is an information to the reader. However, I thought that »Any other concatenations are conditionally-supported with implementation-defined behavior.« might apply to ("a"s"b"s). This is not relevant: But just for fun, I'd like to mention the fact that my compiler with all the »-pedantic -pedantic-errors -Wall -W -Wextra« accepts ("a"s"b"s) without a diagnostic as "ab"s, but I was using a sort of 5.1.1, which might be pre-alpha. »User-defined Literals« where being described in n2765, which contained the wording: »In translation phase 6 (2.1 lex.phases), adjacent string literals are concatenated and user-defined-string-literals are considered string literals for that purpose.« But the last two lines do not seem to have found their way into the standard. However, maybe they led some compiler manufacturers to implement it this way. In the web, I can even find traces of C++0x drafts where this wording /was/ used. |
ram@zedat.fu-berlin.de (Stefan Ram): Jun 13 03:30AM >OK, I take it back. User-defined literals are treated as string >literals. Which document are you looking at, exactly? I am looking at >n4431, which is a draft. Thank you! I only now have found this in the standard. It's (this must be what you refer to above) in 2.13.8p8. Insofar, I also take back parts of my previous post. |
legalize+jeeves@mail.xmission.com (Richard): Jun 13 03:20AM [Please do not mail me a copy of your followup] Now that I am home and have access to my 4th edition of "The C++ Programming Language", I looked up where the code you qouted appears. It is in the middle of pg. 125, section 5.4.2.1 iterator_traits, the first section in 5.4.2 Type Functions. Doug Mika <dougmmika@gmail.com> spake the secret code >2)What is Iterator_type and Iterator_category? I searched for these on >www.cplusplus.com but found nothing that would make it clear. Did you continue reading after the code you quoted? At the bottom of page 125, it provides the definitions for Iterator_type and Iterator_category. (Aside: I find <http://en.cppreference.com/w/> a much better online reference than cplusplus.com; it is more current with the language and being a wiki it is constantly improved by many people instead of whoever is "The C++ Resources Network".) If this is your first exposure to C++, I might suggest that you start with the much shorter book by Stroustrup "A Tour of C++". <http://amzn.to/1FQxUd4> At only 192 pages, it is a much better introduction to modern C++. While I like the detail provided in "The C++ Programming Language", it frequently digresses into every little nook and cranny of the language. Many of these digressions are not necessary for a working knowledge of C++ on a day to day basis.o After you have a working knowledge of the language, then you can revisit all those nooks and crannies and discover the deeper insights of template metaprogramming and the like. But if your experiences so far as a programmer is the typical programming in a block structured language like Java or C#, then diving right into the depths of C++ can be confusing and overwhelming. -- "The Direct3D Graphics Pipeline" free book <http://tinyurl.com/d3d-pipeline> The Computer Graphics Museum <http://computergraphicsmuseum.org> The Terminals Wiki <http://terminals.classiccmp.org> Legalize Adulthood! (my blog) <http://legalizeadulthood.wordpress.com> |
Victor Bazarov <v.bazarov@comcast.invalid>: Jun 12 07:15PM -0400 On 6/12/2015 5:40 PM, Stefan Ram wrote: > an intentionally uninformative subject line »Quick simple > question:«. Possibly, I will not continue this beyond this > subject-line awareness day. Lame! I encounter this every day on the road. If some a$$#ole feels offended by your mere presence on the same road, or just wants to show his (it's most often males) imagined superiority, they will try to cut you off, spray the windshield washer fluid when you are behind them and behave in some other obnoxious way to "learn you a lesson". Don't behave like those idiots. Give a *good example* and *refrain from preaching*. You haven't earned the right to preach, especially after you have not practiced when you're about to preach. OK? V -- I do not respond to top-posted replies, please don't ask |
Victor Bazarov <v.bazarov@comcast.invalid>: Jun 12 07:20PM -0400 On 6/12/2015 5:53 PM, Stefan Ram wrote: > this suggestion on subsequent posts. > Instead we still get more and more subjects lines, > like, recently: »Quick simple question:«. And? Instead of explaining what you mean, you start mimicking them (supposedly in hopes that they notice how absurd such behaviour is and will understand all by themselves that you're trying to show them how to do by doing the exact opposite). They don't care! All you do is look ridiculous yourself. Whatever your intention is, however good it might be, it is only known to *you*. Don't presume that everybody thinks the same or sees/notices the same aspects of life. V -- I do not respond to top-posted replies, please don't ask |
legalize+jeeves@mail.xmission.com (Richard): Jun 12 10:47PM [Please do not mail me a copy of your followup] Doug Mika <dougmmika@gmail.com> spake the secret code >Unfortunately mine doesn't. So here is a question, does anyone know of a >work around for this problem on MinGW or better yet, is there even a >windows compiler that supports all the defined C++11 standards? Clang for Windows (either in MinGW style mode or using CL.EXE compatible command-line arguments) supports all of C++11. <http://llvm.org/releases/download.html> Visual Studio 2013 Community Edition (2015 will be out soon) supports a good chunk of C++11: <https://www.visualstudio.com/> See <http://en.cppreference.com/w/cpp/compiler_support> for a breakdown of support by feature. If you consult that page, please be sure to check the Discussion link as well for additional information. <http://en.cppreference.com/w/Talk:cpp/compiler_support> -- "The Direct3D Graphics Pipeline" free book <http://tinyurl.com/d3d-pipeline> The Computer Graphics Museum <http://computergraphicsmuseum.org> The Terminals Wiki <http://terminals.classiccmp.org> Legalize Adulthood! (my blog) <http://legalizeadulthood.wordpress.com> |
legalize+jeeves@mail.xmission.com (Richard): Jun 12 10:44PM [Please do not mail me a copy of your followup] Joe <no.spam@noemail.com> spake the secret code >So to create a simple object of MyClass, I tried something like this. > std::unique_ptr<MyType<nullptr>> mt; > mt = std::unique_ptr<MyType<nullptr>> { new MyClass(); }; This works for me: #include <memory> template <class MyType> class MyClass { private: std::shared_ptr<MyType> tvar; public: MyClass() {} MyClass(std::shared_ptr<MyType> myT) : tvar(myT) {} }; int main() { MyClass<void> v; return 0; } ...although the example provided feels pedantic. -- "The Direct3D Graphics Pipeline" free book <http://tinyurl.com/d3d-pipeline> The Computer Graphics Museum <http://computergraphicsmuseum.org> The Terminals Wiki <http://terminals.classiccmp.org> Legalize Adulthood! (my blog) <http://legalizeadulthood.wordpress.com> |
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