Saturday, June 13, 2015

Digest for comp.lang.c++@googlegroups.com - 25 updates in 10 topics

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: