Sunday, December 29, 2019

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

Jorgen Grahn <grahn+nntp@snipabacken.se>: Dec 29 11:08AM

On Sun, 2019-12-29, T wrote:
>> be as offtopic as the other recent ones from you. I don't see how to
>> help you with this problem, from a comp.lang.c++ point of view.
 
> What I need to know is the construction of a C++ string
 
Fine, here it is:
 
https://en.cppreference.com/w/cpp/string/basic_string/basic_string
 
Imagine the Allocator stuff isn't there and mentally replace CharT
with char, and you have your normal std::string.
 
/Jorgen
 
--
// Jorgen Grahn <grahn@ Oo o. . .
\X/ snipabacken.se> O o .
Bart <bc@freeuk.com>: Dec 29 12:09PM

On 29/12/2019 10:33, T wrote:
 
>>      Bo Persson
 
> Thank you.  Exactly the same as Modula2.
 
> Is it the same for C++?
 
These are the msdn ('msdn messagebox') docs for MessageBox:
 
int MessageBox(
HWND hWnd,
LPCTSTR lpText,
LPCTSTR lpCaption,
UINT uType
);
 
This is in a panel labelled 'C++', but has been around since it used to
be C. Looking at those string types here:
 
https://docs.microsoft.com/en-us/windows/win32/winprog/windows-data-types
 
LCPCSTR ends up (if you follow the chain of typedefs) as either a type
that points to sequence to 8-bit bytes, terminated by a 0 byte, or a
sequence of 16-bit words, terminated by a 0 word.
 
This latter depends on whether the macro UNICODE is defined inside
windows.h. It will call MessageBoxW if defined, and MessageBoxA if not.
This is rather interesting, since when calling from another language,
windows.h doesn't exist, so there is no such macro.
 
In fact, there is no actual function called "MessageBox", that's just an
artefact of windows.h.
 
Now, when I call MessageBox from my own non-C code, I directly call
MessageBoxA with normal 8-bit zero-terminated strings. I assume the
declaration of this function is as follows:
 
int MessageBoxA(
int hWnd,
char* Text,
char* Caption,
unsigned int Type
);
 
(I don't even use 'const char*', as 'const' is an artefact of the C
language; it has no meaning at the binary level. Here 'int' is assumed
to be 32 bits.)
Barry Schwarz <schwarzb@delq.com>: Dec 29 08:39AM -0800


>Hi All,
 
>I have four different way of converting a Raku/Perl6 string
>into a C++ string to pass to native call. Three come out
 
The word string has two defined meanings in the C++ language. One is
the name of a type (std::string) defined in the Standard Template
Library. The other is an array of characters terminated by a 0 value
as defined in the C standard which is included in C++ by reference.
Which one do you mean?
 
What does "native call" mean? Is it to a C (or C++) function? What
does that function expect? Show us the prototype of the function.
 
>the same and one comes out with a 0x0000 (hex) at the end.
 
No they did not. The last three are significantly different from each
other.
 
>The "say" functions shows me each byte in the converted
>string. Which one is correct?
 
No, say did not show you that. It showed you its interpretation of
the argument you gave it. At the very least, it did not show you
seven bytes of data in the uint16 array.
 
Furthermore, none of the results is a std::string and only one of the
results is a C-style string.
 
>The following is "abcdefg" converted to a C string,
>"wstr", etc. is the method I used and is not part
>of the C string:
 
Something appears to be missing from this sentence. What is the
method you used? And what is not part of what?
 
>97 98 99 100 101 102 103 wstr
>97 98 99 100 101 102 103 0 to-c-str
 
This is a valid C-style string consisting of eight bytes/characters.
 
>97 98 99 100 101 102 103 CArray[uint8].new
 
This is an array of seven bytes/integers that may be considered
characters but it is not a string.
 
>97 98 99 100 101 102 103 CArray[uint16].new
 
This is an array of fourteen bytes (seven integers) that may be
considered wide characters but it is not a string.
 
>And why do I care if I am using "uint8" or "uint16"
>to convert visable text? What about the one
 
You care because the function you are calling may expect one or the
other (or possibly have code to let it determine which you provided
but that is unlikely).
 
>with the 0 at the end?
 
This is the only one that is a string. Whether that matters depends
on the function you are calling.
 
--
Remove del for email
Barry Schwarz <schwarzb@delq.com>: Dec 29 08:45AM -0800

On Sun, 29 Dec 2019 12:17:08 +0200, Paavo Helde
 
>In C, a string is commonly represented just as an array of characters.
>The length of the array may be indicated by a terminating zero
>character, or the length might be passed separately.
 
In order for the array to be a string, it must have a terminating
zero. Non-string arrays can use other termination characters or have
the length specified separately but by definition they are not
strings.
 
--
Remove del for email
T <T@invalid.invalid>: Dec 29 11:50AM -0800

On 2019-12-29 03:08, Jorgen Grahn wrote:
 
> Imagine the Allocator stuff isn't there and mentally replace CharT
> with char, and you have your normal std::string.
 
> /Jorgen
 
Hi Jorgen,
 
I figured out through experimentation that Native Call
automatically add the chr(0) on to the end of a CString.
 
And that sending Native Call a zero gets automatically
changed into a NULL. Hmmm, I wonder what happens
if you really what a numerical zero. That will be a
test for another day.
 
Thank you all for all the wonderful help!
 
-T
T <T@invalid.invalid>: Dec 29 11:51AM -0800

On 2019-12-29 04:09, Bart wrote:
 
> (I don't even use 'const char*', as 'const' is an artefact of the C
> language; it has no meaning at the binary level. Here 'int' is assumed
> to be 32 bits.)
 
Hi Bart,
 
I figured out through experimentation that Native Call
automatically adds the chr(0) on to the end of a CString.
 
And that sending Native Call a zero gets automatically
changed into a NULL. Hmmm, I wonder what happens
if you really what a numerical zero. That will be a
test for another day.
 
Thank you all for all the wonderful help!
 
-T
T <T@invalid.invalid>: Dec 29 11:54AM -0800

On 2019-12-29 08:45, Barry Schwarz wrote:
> zero. Non-string arrays can use other termination characters or have
> the length specified separately but by definition they are not
> strings.
 
Hi Barry,
 
I figured out through experimentation that Native Call
automatically adds the chr(0) on to the end of a CString.
 
And that sending Native Call a zero gets automatically
changed into a NULL. Hmmm, I wonder what happens
if you really what a numerical zero. That will be a
test for another day.
 
Trivia: I can stick all the chr(0) in a Raku/Perl6
string I want and in any position I want. But
a Raku string is a "data structure", not an "array of
characters". The end of the string is in the structure,
not the string itself.
 
Thank you all for all the wonderful help!
 
-T
T <T@invalid.invalid>: Dec 29 12:02PM -0800

On 2019-12-29 02:56, Öö Tiib wrote:
> Most of the people posting or reading this group do not really care
> about it and the few that do can find the appropriate forums just
> fine.
 
Hi Öö,
 
Well now, I am glad you asked!
 
I pound those guys with questions. I even get on Raku's
chat line.
 
The reason I post here, is because those guys very
little knowledge of C and C++ and, well, you guys do.
Plus, there are a lot of mensches on this list.
 
And now that I ksow what is going on on he C and C+++
side, I understand much better how to use Raku's Native
Call. Oh ya, and with you guys help and other help
from varoius places, I tracked down a bug in
RegQueryValueExW that I now know how to work around
(always send lpType a NULL despite what the documentation
says).
 
Thank you all for the wonderful help!
 
-T
 
By the way, I do not program in C or C++ for the simple
reason that I ADORE Raku and -- well to put it
bluntly -- I am not smart enough to program in C or C++.
My hat going off to your guys.
T <T@invalid.invalid>: Dec 29 12:10PM -0800

On 2019-12-29 08:39, Barry Schwarz wrote:
> Which one do you mean?
 
> What does "native call" mean? Is it to a C (or C++) function? What
> does that function expect? Show us the prototype of the function.
 
Hi Barry,
 
Native Call is a module (documented by Satin himself)
in Raku/Perl6 that allows you to make system calls to .so
and .dll's.
 
 
> No, say did not show you that. It showed you its interpretation of
> the argument you gave it. At the very least, it did not show you
> seven bytes of data in the uint16 array.
 
Which was what I was after.
 
> Furthermore, none of the results is a std::string and only one of the
> results is a C-style string.
 
Native call converts this to a C string for you. It is
not documented very well.
 
 
 
> You care because the function you are calling may expect one or the
> other (or possibly have code to let it determine which you provided
> but that is unlikely).
 
Native Call adds the chr(0) to the end for you. This
I had to find out through experimentation.
 
 
>> with the 0 at the end?
 
> This is the only one that is a string. Whether that matters depends
> on the function you are calling.
 
Since "W" calls use uint16, I settled on
my $M = CArray[uint16].new("abcdefg".encode.list);
for simplicity.
 
Thank you for the wonderful help! On my journey, I hit
a few curbs, ran over a fire hydrant, hit a squirrel
(that "might" have been on purpose, I ain't saying) but
I got there eventually!
 
-T
Keith Thompson <Keith.S.Thompson+u@gmail.com>: Dec 29 01:57PM -0800


>> No, from a C perspective "A string is a contiguous sequence of
>> characters terminated by and including the first null character."
 
> Do I need the chr(0) at the end?
 
I presume that by "chr(0)" you mean the char value '\0', also known as
the null character. Your meaning is reasonably clear, but there is no
"chr" function in C or C++.
 
Yes, by definition a "string" includes the terminating null character.
If there's no null character, it's not a string.
 
--
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 */
Keith Thompson <Keith.S.Thompson+u@gmail.com>: Dec 29 01:57PM -0800

T <T@invalid.invalid> writes:
[...]
> if you really what a numerical zero. That will be a
> test for another day.
 
> Thank you all for all the wonderful help!
 
You're talking about Raku/Perl6, right?
 
Things you find out through experimentation aren't always reliable.
It's possible that the Raku native call interface (which I haven't
looked at) doesn't distinguish between a numerical zero and a null
pointer. If that's the case, it could work with any C++ implementation
that represents a null pointer as all-bits-zero. That's likely to be
all existing C++ implementations, or at least all C++ implementations
that Raku might interface with. It's not guaranteed by the C++
standard, though. A literal 0 is a *null pointer constant*, but that
doesn't imply that a *null pointer* is represented as all-bits-zero.
 
--
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 */
Keith Thompson <Keith.S.Thompson+u@gmail.com>: Dec 29 01:57PM -0800

>> be as offtopic as the other recent ones from you. I don't see how to
>> help you with this problem, from a comp.lang.c++ point of view.
 
> What I need to know is the construction of a C++ string
 
What exactly do you mean by a "C++ string"? Are you asking about the
std::string class defined in the <string> header?
 
If so, what about the construction of a std::string object are you
asking about? Most of the internal details are unspecified.
 
C++ also has C-style strings, referred to in the standard as
"null-terminated byte strings" (and often referred to as "C-strings"
or something similar).
 
--
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 */
T <T@invalid.invalid>: Dec 29 02:57PM -0800

On 2019-12-29 13:57, Keith Thompson wrote:
> "chr" function in C or C++.
 
> Yes, by definition a "string" includes the terminating null character.
> If there's no null character, it's not a string.
 
It soaked in. Thank you!
T <T@invalid.invalid>: Dec 29 03:00PM -0800

On 2019-12-29 13:57, Keith Thompson wrote:
>> test for another day.
 
>> Thank you all for all the wonderful help!
 
> You're talking about Raku/Perl6, right?
 
Yes. Once I understood what was going on in C++,
I was able to get my code working.
 
> that Raku might interface with. It's not guaranteed by the C++
> standard, though. A literal 0 is a *null pointer constant*, but that
> doesn't imply that a *null pointer* is represented as all-bits-zero.
 
The Raku Native Call documentation is so, so bad
your only choice is experimentation.
 
NULL was a nightmare for me to figure out. Once I did,
it was so simple it made my head spin
 
That you again for the wonder teaching!
-T
T <T@invalid.invalid>: Dec 29 03:02PM -0800

On 2019-12-29 13:57, Keith Thompson wrote:
 
> C++ also has C-style strings, referred to in the standard as
> "null-terminated byte strings" (and often referred to as "C-strings"
> or something similar).
 
Hi Keith,
 
I figured it out.
 
Native call is converting to C anyway. This is from my
Navice Call notes:
 
3) a "C" string is an array of characters terminated with chr(0)
 
4) Kernel32.dll calls with a "W" in them use UTF16 `uint16` values
in their strings. The rest you can use UTF8 `uint8`. Most of
the time they are interchangeable if you are using standard
characters.
 
Use the following to convert a Raku strings, `abcdefg` below,
into a "C" string
 
UTF8: my $L = CArray[uint8].new("abcdefg".encode.list);
UTF16: my $M = CArray[uint16].new("abcdefg".encode.list);
 
Native Call is tack the chr(0) at the end for you.
 
 
 
Thank you again for all the wonderful teaching!
 
-T
Manfred <noname@invalid.add>: Dec 29 05:52PM +0100

On 12/29/19 2:16 AM, T wrote:
>> native calls.
 
> It does.  Raku's documents are really badly written at the moment.
 
> https://docs.perl6.org/language/nativecall#Basic_use_of_pointers
 
I see that it says that perl6 provides a Pointer type that can hold
pointers.
The very last sentence says "Once again, type objects are used to
represent NULL pointers."
I don't know what "type objects" are in Perl (this kind of confusion
between types and objects is one of the reasons why I hate scripting
languages), but I guess this should mean something to someone more
familiar with that language.
 
T <T@invalid.invalid>: Dec 29 12:21PM -0800

On 2019-12-29 08:52, Manfred wrote:
> between types and objects is one of the reasons why I hate scripting
> languages), but I guess this should mean something to someone more
> familiar with that language.
 
Hi Manfred,
 
The documentation is such rubbish.
 
What I had to find out through experimentation
was that Native Call creates the C NULL for you
when you pass it a zero. It begs the question
if you actually wanted to pass a numerical zero.
 
If you pass it an "type object", it errors out
on you (crappy documentation).
 
And if you are expecting to get a pointer back,
you won't. Native call extracts the value for you.
Again, crappy documentation.
 
Native Call also tacks on a chr(0) to a C String
automatically for you too. More crappy documentation.
 
When my programs hit over 4000 lines, I would not
refer to it as a "Scripting Language".
 
Raku a hybrid language. First it gets interpreted, then
the OPCODE gets compiled. It allows you to create
code TWICE as FAST as a pure compiled language, but
also runs TWICE as SLOW. (I am not smart enough
to program in C or C++ either.)
 
Thank you all for the help. I FINALLY have it
all figured out!
 
-T
 
 
 
 
 
Keith Thompson <Keith.S.Thompson+u@gmail.com>: Dec 29 01:31PM -0800

>> represented. How is it useful? Most of the time, the representation
>> doesn't matter.
 
> Knowing it's useful in that it enables me to use it.
 
I'm about to give up on this conversation, since it seems unlikely to go
anywhere useful.
 
99% of the time, there is no good reason to care in C++ how a null
pointer, or any other pointer value, is represented. It's an
abstraction. You can write C++ code that uses null pointers, and you
haven't done anything unnecessarily tricky, your code will work
correctly on implementations with different representations.
 
How exactly does knowing how null pointers are represented make it
easier to use them?
 
 
> Except for that last phrase "but they're rare", your statement amounts to
> an acceptance (inadveratant, I'm sure) of what I'm saying. You agree that
> "there are cases"; their rarity or otherwise is irrelevanbt.
 
You've decided that rarity is irrelevant. Perhaps it is for whatever
you're talking about (I still haven't quite figured out what that is).
I acknowledge, of course, that there are some cases in very low-level
code where knowing pointer representation is useful. The rarity of
those cases is extremely relevant to what I'm talking about.
 
 
>> Do you mean "(void*)0"?
 
> Not particularly. (void*) applies safely to variables on systems where
> sizeof(int) == sizeof(void*).
 
What variables? Of what type(s)? Are you saying that something like
`(void*)42` is useful?
 
>> why do you prefer it to NULL or nullptr? What do you mean by "switching
>> between constant and variable"?
 
> Pointer arithmetic.
 
I still don't know the answer to my question. Perhaps an example would
help.
 
Please take a moment to consider that I really don't know what you're
talking about, and that perhaps that's because you haven't explained it
clearly.
 
Pointer arithmetic does not depend on the representation of pointers.
It's an abstraction defined in terms of the objects the pointers point
to. Of course the implementation depends on the representation, but if
you're not writing a compiler you *probably* don't need to care about
that.
 
I've worked on systems where this:
char *ptr = ...;
char *p1 = ptr + 1;
char *p2 = (char*)((int)ptr + 1);
would give p1 and p2 different values (and sizeof (int) == sizeof (char*)).
 
 
>> > Precisely.
 
>> Precisely what?
 
> It's valid for pointers. If that's useful, use it.
 
Yes, of course. And it has nothing to do with pointer representation.
It doesn't support you claim that knowing how pointers are represented
is useful.
 
 
>> Perhaps I'm missing something. What exactly was your point?
 
> I've stated it in every post in this thread. Knowing how NUL is
> represented can be useful.
 
It's spelled NULL.
 
I don't dispute that it *can* be useful. I disagree that it's useful in
general. In particular, I can write code without knowing or caring how
a null pointer is represented, and that will work correctly under
different implementations that represent it differently.
 
Languages define abstractions precisely so programmers don't have to
worry about the underlying details.
 
--
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 */
Chris Vine <chris@cvine--nospam--.freeserve.co.uk>: Dec 29 11:31AM

On Sun, 29 Dec 2019 09:00:09 +0000 (UTC)
> >are not to give rise to any additional allocations on the heap, and the
 
> Thats all well and good, but if the contained object DOES do its own further
> dynamic allocations or assignments then there will be allocations on the heap.
 
If the contained object happens to do its own allocations it does its
own allocations, whether or not it is contained in a variant. You are
missing the point I am afraid, so far as you ever had one. You
claimed variants or options would give rise to additional allocations
and would therefore be inefficient in use. The standard prohibits
such additional allocations: end of story.
 
> >unions (but with type safety). In most uses they will be significantly
 
> The whole point of C unions is that they're NOT type safe. A type safe union
> is a contradiction.
 
The whole point of variants is that they ARE type safe. You should
stick to your original plan of giving up.
 
> >std::visit are reasonably easy to write in C++17.
 
> Don't get me started on the visitor pattern - an absolute joke of a "solution"
> looking for a problem.
 
std::visit for variants isn't concerned with the GoF visitor pattern.
 
> >of a teenager.
 
> If thats your opinion then do kindly go fuck yourself you patronising cunt
> (as Flibble might say).
 
I must decline your invitation. I imagine it is probably the opinion of
anyone reading your posts, so your suggestion would give rise to an
excessive amount of self-copulation taking place. If you carry on like
this your mummy is going to send you to your bedroom without your
supper.
boltar@nowhere.org: Dec 29 06:30PM

On Sun, 29 Dec 2019 12:21:33 +0200
>strength of C++ is to build higher level abstractions, in particular
>typesafe and zero overhead abstractions over low-level unsafe primitives
>like C unions.
 
The whole point of a union is not to save memory, its to write as one type
and read as another , eg fill a char buffer from a network interface and read
it out as packet fields. An "unsafe" C union would be a useless C union.
And as such a variant is not a union. I'm sure it has its niche uses but
I've yet to see a convincing one that couldn't have been done in a clearer
more expandable way.
boltar@nowhere.org: Dec 29 06:35PM

On Sun, 29 Dec 2019 11:31:00 +0000
>claimed variants or options would give rise to additional allocations
>and would therefore be inefficient in use. The standard prohibits
>such additional allocations: end of story.
 
Used with any useful objects , eg even a string value that is modified on the
fly beyond any fixed sized internal array then any hope of storing all data
on the stack goes out the window.
 
>> is a contradiction.
 
>The whole point of variants is that they ARE type safe. You should
>stick to your original plan of giving up.
 
The whole point of variants is .... beats me. Memory isn't an issue these
days and you wouldn't be using them programming a PIC anyway, and they do not
perform the type punning like a C union, which is the whole point of the latter.
 
>excessive amount of self-copulation taking place. If you carry on like
>this your mummy is going to send you to your bedroom without your
>supper.
 
Don't project your own personal circumstances onto those of others, it only
ends in embarrasment.
Mr Flibble <flibble@i42.removethisbit.co.uk>: Dec 29 06:40PM

>> supper.
 
> Don't project your own personal circumstances onto those of others, it only
> ends in embarrasment.
 
The only embarrassment here is your pathetic attempts at trolling to try
to hide the fact that you fucked up. You are wrong and you know it.
 
/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."
Paavo Helde <myfirstname@osa.pri.ee>: Dec 29 09:45PM +0200

>> like C unions.
 
> The whole point of a union is not to save memory, its to write as one type
> and read as another ,
 
You wish. However, this is undefined behavior by the standard.
 
12.3 [class.union]:
 
"In a union, a non-static data member is active if its name refers to an
object whose lifetime has begun and has not ended (6.8). At most one of
the non-static data members of an object of union type can be active at
any time."
 
Accessing an object outside of its lifetime is UB. The only exception is
for matching common initial sequences, which is not what you are talking
about.
 
It's true that some C++ implementations support type punning via unions
as an extension, but by the letter of standard this is still UB and
relying on this will make the code unportable.
 
> eg fill a char buffer from a network interface and read
> it out as packet fields.
 
There is no special exception for unions containing a char array.
Daniel <danielaparker@gmail.com>: Dec 29 12:11PM -0800

On Sunday, December 29, 2019 at 6:30:55 AM UTC-5, Chris Vine wrote:
> On Sun, 29 Dec 2019 09:00:09 +0000 (UTC)
 
> > kindly go fuck yourself
> > (as Flibble might say).
 
While it's always interesting to speculate on what our excellent Mr Flibble
might say, I doubt if he would say exactly this, as I don't recall him
previously suggesting an anatomically impossibility.
 
> I must decline your invitation.
 
Nice way to bring things back on topic, to optionality.
 
Daniel
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: