- Question on a C++ string - 15 Updates
- What is the data structure of a NULL? - 3 Updates
- Don't be fooled by cpp.sh - 6 Updates
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:
Post a Comment