Sunday, June 9, 2019

Digest for comp.lang.c++@googlegroups.com - 14 updates in 3 topics

G G <gdotone@gmail.com>: Jun 08 04:58PM -0700

i'm just wondering if i got lucky and the
cout << "Length of string in charr before input: "
<< strlen(charr) << endl;
 
return a 0, zero, because '\0' happened to be the first char in the
array charr ?
 
thanks.
---------------------------------------------------------
program from: Stephen Prada C++ Primer Plus p.137
 
// strtype4.cpp -- line input
 
#include <iostream>
#include <string>
#include <cstring>
 
int main()
{
using namespace std;
 
char charr[20];
string str;
 
cout << "Length of string in charr before input: "
<< strlen(charr) << endl;
 
cout << "Length of string in str before input: "
<< str.size() << endl;
 
cout << "Enter a line of text:\n";
 
cin.getline(charr, 20);
 
cout << "You entered: " << charr << endl;
 
cout << "Enter another line of text:\n";
getline(cin, str);
 
cout << "You entered: " << str << endl;
 
cout << "Length of string in char after input: "
<< strlen(charr) << endl;
 
cout << "Length of string in str after input: "
<< str.size() << endl;
 
return 0;
}
"Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com>: Jun 09 02:53AM +0200

On 09.06.2019 01:58, G G wrote:
> << strlen(charr) << endl;
 
> return a 0, zero, because '\0' happened to be the first char in the
> array charr ?
 
Yes. A not explicitly initialized local POD variable has indeterminate
value. In the case of byte type it's in practice OK to access the value,
but a string length function can easily go beyond the end of the array
and then the formal Undefined Behavior can become very manifest.
 
 
> thanks.
> ---------------------------------------------------------
> program from: Stephen Prada C++ Primer Plus p.137
 
Thanks, it's useful for readers to know which book it is.
 
 
> string str;
 
> cout << "Length of string in charr before input: "
> << strlen(charr) << endl;
 
This is UB. This may be the last statement that's executed, depending on
luck or not.
 
 
> << str.size() << endl;
 
> cout << "Enter a line of text:\n";
 
> cin.getline(charr, 20);
 
Using magic constants is an ungood practice. Should have used `sizeof`
here. If the book had been more modern, should have used C++17
`std::size`, or even more modern, should have used C++20 `std::ssize`. ;-)
 
 
 
> cout << "Length of string in str after input: "
> << str.size() << endl;
 
> return 0;
 
This statement is redundantly expressing the well known default.
 
> }
 
 
Cheers & hth.,
 
- Alf
Juha Nieminen <nospam@thanks.invalid>: Jun 09 10:22AM

> char charr[20];
 
No. Static arrays of basic types are not initialized. They are not
guaranteed to contain any specific values. In order to initialize them
you have to say so explicitly:
 
char charr[20] = {};
 
This will make the entire array zero-initialized.
 
If you want to bypass zero-initializing *the entire* array, and only
would want the first value to be zero, the only way to do that is:
 
char charr[20];
charr[0] = 0;
 
(Note that "charr charr[20] = { 0 };" will zero-initialize the entire
array, not just the first value.)
Chris Vine <chris@cvine--nospam--.freeserve.co.uk>: Jun 09 02:45PM +0100

On Sun, 9 Jun 2019 10:22:35 -0000 (UTC)
> > char charr[20];
 
> No. Static arrays of basic types are not initialized. They are not
> guaranteed to contain any specific values.
 
A slip of the keyboard: I think you meant that non-static arrays of
basic types are not initialized (static ones are zero initialized).
Keith Thompson <kst-u@mib.org>: Jun 09 12:07PM -0700


> thanks.
> ---------------------------------------------------------
> program from: Stephen Prada C++ Primer Plus p.137
 
(It's "Prata". Which edition?)
 
> string str;
 
> cout << "Length of string in charr before input: "
> << strlen(charr) << endl;
[...]
> return 0;
> }
 
No, you got *unlucky*, or rather Stephen Prata did.
 
charr is initialized with arbitrary garbage (I carefully avoided
the word "random"), so strlen(charr) has undefined behavior.
 
If charr[0] happens to contain a '\0', that means the program has a bug
that's going to be difficult to diagnose, and will probably show up at
the most inconvenient possible time (in this case, after the book has
been published).
 
Can you submit an error report to the publisher?
 
--
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 */
Melzzzzz <Melzzzzz@zzzzz.com>: Jun 09 07:11PM


> No, you got *unlucky*, or rather Stephen Prata did.
 
> charr is initialized with arbitrary garbage (I carefully avoided
> the word "random"), so strlen(charr) has undefined behavior.
 
You mean, not initialized... interrestingly languages like D that
initialize variables before use, have hacks not to do that.
 
 
--
press any key to continue or any other to quit...
U ničemu ja ne uživam kao u svom statusu INVALIDA -- Zli Zec
Na divljem zapadu i nije bilo tako puno nasilja, upravo zato jer su svi
bili naoruzani. -- Mladen Gogala
G G <gdotone@gmail.com>: Jun 09 12:47PM -0700

On Sunday, June 9, 2019 at 3:08:09 PM UTC-4, Keith Thompson wrote:
> 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 */
 
i should have made it clear that in the book, the run of the program does not
return 0. in the book the value was 27 and the author explained that content
is an uninitialized array are undefined and it probably stopped at 27 because it
just happened to have a '\0' at that location.
 
sorry i didn't make that clear. my thought was perhaps that C++17 or new had
made a change... or i just luckily had a '\0' at the beginning of that array and that's
why i got an zero, 0, for the length.
 
the book edition is the sixth edition.
i'm using clang-900.0.39.2
 
sorry for the confusion everyone
Melzzzzz <Melzzzzz@zzzzz.com>: Jun 09 08:49PM


> sorry i didn't make that clear. my thought was perhaps that C++17 or new had
> made a change... or i just luckily had a '\0' at the beginning of that array and that's
> why i got an zero, 0, for the length.
Since accessing unitialized variable is undefined there is no point in
discussing further...
 
--
press any key to continue or any other to quit...
U ničemu ja ne uživam kao u svom statusu INVALIDA -- Zli Zec
Na divljem zapadu i nije bilo tako puno nasilja, upravo zato jer su svi
bili naoruzani. -- Mladen Gogala
G G <gdotone@gmail.com>: Jun 08 05:35PM -0700

p. 146 C++ Primer Plus, Stephen Prata
 
example:
 
struct // no tag
{
int x; // 2 members
int y;
} position; // a structure variable
 
when would something where the tag is omitted be useful?
Juha Nieminen <nospam@thanks.invalid>: Jun 09 10:29AM

> int y;
> } position; // a structure variable
 
> when would something where the tag is omitted be useful?
 
"struct { something }" acts pretty much as a type, and can be
used anywhere where a type could be used. You don't have to create
a type alias for it if you don't want to. Thus code like this is
perfectly valid:
 
struct { int a, b; } values = { 1, 2 };
std::cout << values.a << " " << values.b << "\n";
 
Now, whether that's extraordinarily *useful*... I can't think of
any situation where it would be particularly useful over a named
struct type. Maybe in extremely simple situations like the above,
where you simply want to group a number of values into a "packet"
in that manner, and not create a new name for it. But even then,
you aren't saving much, really.
Sam <sam@email-scan.com>: Jun 09 07:46AM -0400

G G writes:
 
> int y;
> } position; // a structure variable
 
> when would something where the tag is omitted be useful?
 
Mostly when someone is coding in C, but there are some occasions where a
structure is used only once, for a very specific purpose, within a function
scope, and it serves no point to declare the structure formally. Such as,
using an example from real C++ code, and not a contrived example from a
garbage C++ book:
 
static const struct {
const char *name;
font &(font::*handler)(double);
} double_values[]={
{ "point_size", &font::set_point_size},
{ "scaled_size", &font::set_scaled_size},
{ "scale", &font::scale},
};
 
for (const auto &v:double_values)
{
// ...
 
Need a mapping between symbolic labels and class methods here. Simply
declare an anonymous struct and iterate over it, doing what needs to be done.
 
No need to formally declare this, in some header file, somewhere, when this
is needed just here and nowhere else.
 
P.S., it's not a "tag", but a class name. Given the other garbage example
you showed from this so-called "C++ book", you might consider returning it
for a refund and getting a better C++ book to learn from. C++ is hard enough
as it is.
jameskuyper@alumni.caltech.edu: Jun 09 01:30PM -0700

On Saturday, June 8, 2019 at 8:35:37 PM UTC-4, G G wrote:
> int y;
> } position; // a structure variable
 
> when would something where the tag is omitted be useful?
 
It is never useful to omit the tag, but it can often be useless to
provide one. Specifically, try writing the code that makes use of the
struct without providing a tag. If you can do so, then you don't need
the tag. This isn't commonplace, but neither is it extremely rare.
 
There's minor advantages to not providing a tag: you don't have to come
up with a name for it, and since it isn't named, it can't conflict with
anything else that happens to have the same name with a different
meaning. I don't go out of my way to write such code, but if I happen to
notice that the tag is not needed, I will often leave it out.
Juha Nieminen <nospam@thanks.invalid>: Jun 09 10:17AM

> values into new vector of the same length as the original two.
 
> I think this can be done with a lambda function? and a mapping function
> on the vectors but don't immediately know the procedure I would use.
 
I find this question extraordinarily confusing. I find it confusing
because, I suppose, I don't really understand what you are asking.
 
Iterating through a couple of vectors, xorring the elements and
assigning the result into a third vector is a 2-liner. And it's not
like it's some really obscure highly-technical hacker-trick that you
need deep understanding of C++ or programming to do. It's an extremely
simple, even trivial, thing to do, even for a complete beginner. Just
write a single for-loop with an assignment as its body. Two lines of
very simple code.
 
So, because this is so simple, I'm suspecting that's *not* what you
are really asking. You seem to be asking something else. But what,
exactly?
 
Maybe you are asking if there's an even faster way of doing that
other than just iterating through the vectors? You could most certainly
improve on the speed of that task by helping the compiler to vectorize
the code (ie. help it use SIMD instructions to perform the xorring on
4 or even 8 elements at a time), and/or by using multithreading.
Especially the former *is* a bit of a more profound technique that
requires a bit of undrestanding of what the compiler is doing, and what
you can do to help it vectorize the code.
 
However, you then start talking about lambda functions, completely
out of the blue. This confuses me even more. Maybe you aren't actually
talking about how to make the code faster. Maybe when you say
"efficient" you are not talking about execution speed, but something
else? Why would you be talking about lambda functions if all you cared
is executiong speed? What do lambda functions have anything to do with
this? I suspect that you are asking for something else.
 
I just don't understand what.
Mr Flibble <flibbleREMOVETHISBIT@i42.co.uk>: Jun 09 03:21PM +0100

On 09/06/2019 11:17, Juha Nieminen wrote:
> simple, even trivial, thing to do, even for a complete beginner. Just
> write a single for-loop with an assignment as its body. Two lines of
> very simple code.
 
As Jorgen suggested up-thread the idiomatic way to do this is using
std::transform rather than with explicit for-loops and it does indeed make
it a one liner in which use of a lambda would be appropriate if std::xor
didn't exist.
 
/Flibble
 
--
"Snakes didn't evolve, instead talking snakes with legs changed into
snakes." - Rick C. Hodgin
 
"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."
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: