RM <robert_magdziarz@wp.pl>: Jul 31 08:17PM +0200
I have problem with my TRACE macro: there's nothing on output. I have the following definition: #ifdef DEBUG # ifdef _MSC_VER # include <windows.h> # include <sstream> # define TRACE(x) \ do { \ std::stringstream s; \ s << __FILE__ << " (" << __LINE__ << "), " << __FUNCTION__ <<": " << x << std::endl; \ OutputDebugString(s.str().c_str()); \ } while (false) # define TRACE_IF(b, x) if (b) TRACE(x) # else # include <iostream> # define TRACE(x) std::clog << __FILE__ << " (" << __LINE__ << "), " << __FUNCTION__ <<": " << x << std::endl # define TRACE_IF(b, x) if (b) TRACE(x) # endif #else # define TRACE(x) # define TRACE_IF(b, x)
RM <robert_magdziarz@wp.pl>: Jul 31 12:33PM +0200
Napisałem coś takiego: char *tmp_tmplt = const_cast<char *>("/tmp/dirtyphp_XXXXXX"); string tmp_filename = mkstemp(tmp_tmplt); I mam błąd kompilacji: src/obfuscator.cpp: In member function 'std::__cxx11::string obfuscator::check_not_allowed_syntax(std::__cxx11::string, std::__cxx11::string, std::__cxx11::string)': src/obfuscator.cpp:147:34: error: conversion from 'int' to non-scalar type 'std::__cxx11::string {aka std::__cxx11::basic_string<char>}' requested string tmp_filename = mkstemp(tmp_tmplt); ~~~~~~~^~~~~~~~~~~ Nie rozumiem tego błędu ponieważ tmp_tmplt jest typu char* a nie int. | RM <robert_magdziarz@wp.pl>: Jul 31 12:41PM +0200
Sorry I have mistaken newsgroup. Now in English: I wrote: char *tmp_tmplt = const_cast<char *>("/tmp/dirtyphp_XXXXXX"); string tmp_filename = mkstemp(tmp_tmplt); And I have compilation error: src/obfuscator.cpp: In member function 'std::__cxx11::string obfuscator::check_not_allowed_syntax(std::__cxx11::string, std::__cxx11::string, std::__cxx11::string)': src/obfuscator.cpp:147:34: error: conversion from 'int' to non-scalar type 'std::__cxx11::string {aka std::__cxx11::basic_string<char>}' requested string tmp_filename = mkstemp(tmp_tmplt); ~~~~~~~^~~~~~~~~~~ I don't understand the error because tmp_tmplt is of type char*, not int. | Bo Persson <bo@bo-persson.se>: Jul 31 12:54PM +0200
On 2020-07-31 at 12:41, RM wrote: > string tmp_filename = mkstemp(tmp_tmplt); > ~~~~~~~^~~~~~~~~~~ > I don't understand the error because tmp_tmplt is of type char*, not int. Yes, but what does msktemp return? int mkstemp(char *template); The compiler complains about trying to construct the std::string from the int return value. Another problem is that casting away const from the literal isn't going to make it writable. I would expect a runtime error here when testing the code. Bo Persson | RM <robert_magdziarz@wp.pl>: Jul 31 01:44PM +0200
Thank you. I corrected my code. char tmp_filename[21] = "/tmp/dirtyphp_XXXXXX"; close(mkstemp(tmp_filename)); | Keith Thompson <Keith.S.Thompson+u@gmail.com>: Jul 31 11:01AM -0700
> I corrected my code. > char tmp_filename[21] = "/tmp/dirtyphp_XXXXXX"; > close(mkstemp(tmp_filename)); Better: char tmp_filename[] = "/tmp/dirtyphp_XXXXXX"; Let the compiler figure out how big it needs to be. (Computers are really good at counting things.) -- Keith Thompson (The_Other_Keith) Keith.S.Thompson+u@gmail.com Working, but not speaking, for Philips Healthcare void Void(void) { Void(); } /* The recursive call of the void */ | Bo Persson <bo@bo-persson.se>: Jul 31 10:40AM +0200
On 2020-07-30 at 18:37, Juha Nieminen wrote: > guaranteed to be laid out as you want, and their layout > (and even how many bytes they take) may change from compiler > to compiler and system to system. Correct. In addition to all this, and in addition to being little endian or big endian, it is also known that for example VC++ and gcc don't agree on which order to allocate bits. So if Frederick has u8 transparent : 1; u8 reserved0 : 7; The transparent bit will be the high bit with some compilers and the low bit on others. Bo Persson | Scott Newman <scott69@gmail.com>: Jul 31 12:38PM +0200
> u8 reserved0 : 7; > The transparent bit will be the high bit with some compilers and the low > bit on others. The decision is whether the compiler compiles for a big-endian machine or a little-endian machine. A big-endian compiler begins to fill up the bits from the high-bit, a little-endian compiler does it the oppostite way. | Bo Persson <bo@bo-persson.se>: Jul 31 12:46PM +0200
On 2020-07-31 at 12:38, Scott Newman wrote: > or a little-endian machine. A big-endian compiler begins to fill up the > bits from the high-bit, a little-endian compiler does it the oppostite > way. No, that's exactly not the case. Even when you compile for x86, VC++ and g++ will start from opposite ends. The standard allows either way, and that's what happens. Bo Persson | Scott Newman <scott69@gmail.com>: Jul 31 12:48PM +0200
> No, that's exactly not the case. That's what actually happens with the current compilers. | Bo Persson <bo@bo-persson.se>: Jul 31 01:00PM +0200
On 2020-07-31 at 12:48, Scott Newman wrote: >> No, that's exactly not the case. > That's what actually happens with the current compilers. You did notice the example on the very next line, didn't you: "Even when you compile for x86, VC++ and g++ will start from opposite ends. The standard allows either way, and that's what happens." Not everyone believes that gcc on Linux is the entire world when writing portable code. Bo Persson | Scott Newman <scott69@gmail.com>: Jul 31 01:07PM +0200
> "Even when you compile for x86, VC++ and g++ will start from opposite > ends. The standard allows either way, and that's what happens." What the standard says doesn't count. What counts is what current compilers do. You can rely on that a little-endian or big-endian compiler does it like I said since no one would use a compiler that would it different because this would break the conventions. | James Kuyper <jameskuyper@alumni.caltech.edu>: Jul 31 05:09AM -0700
On Friday, July 31, 2020 at 7:07:42 AM UTC-4, Scott Newman wrote: > You can rely on that a little-endian or big-endian compiler does it > like I said since no one would use a compiler that would it different > because this would break the conventions. So, on an x86, since VC++ and g++ do in fact do it differently, one of those two very popular compilers must be one that "no one would use" - which one? I ask because I don't know which one of those does it in a different order than the one you expect - I've used both compilers (which, according to you, makes me "no one"), but it would never occur to me to write code that would require me to know which order they use. | Jorgen Grahn <grahn+nntp@snipabacken.se>: Jul 31 12:11PM
On Fri, 2020-07-31, Bo Persson wrote: >> bits from the high-bit, a little-endian compiler does it the oppostite >> way. > No, that's exactly not the case. As far as I can tell, "Scott Newman" gives plausible but incorrect information on purpose. /Jorgen -- // Jorgen Grahn <grahn@ Oo o. . . \X/ snipabacken.se> O o . | Scott Newman <scott69@gmail.com>: Jul 31 02:13PM +0200
> So, on an x86, since VC++ and g++ do in fact do it differently, one of > those two very popular compilers must be one that "no one would use" - > which one? VC++ behaves like what I said since there are only little-endian targets for VC++. | Bo Persson <bo@bo-persson.se>: Jul 31 02:57PM +0200
On 2020-07-31 at 14:11, Jorgen Grahn wrote: >> No, that's exactly not the case. > As far as I can tell, "Scott Newman" gives plausible but incorrect > information on purpose. The nicest interpretation is that he only uses gcc on Linux, and considers everything else irrelevant. Of course makes it easy for him to write "portable" code. :-) Bo Persson | Scott Newman <scott69@gmail.com>: Jul 31 03:00PM +0200
> The nicest interpretation is that he only uses gcc on Linux, and > considers everything else irrelevant. Of course makes it easy for > him to write "portable" code. :-) I'm neither talking about gcc, nor MSVC or whatever. Regarding the placement of bitfields you can simply distinguish between compilers for big-endian and little-endian targets. | James Kuyper <jameskuyper@alumni.caltech.edu>: Jul 31 08:15AM -0700
On Friday, July 31, 2020 at 8:14:06 AM UTC-4, Scott Newman wrote: > > which one? > VC++ behaves like what I said since there are only little-endian targets > for VC++. I've only ever used VC++ because my employer choose it for the application they were paying me to work on. I had no need or interest in knowing whether it supports big-endian targets. Therefore, I'll take your word for that - (or maybe I won't - your reputation for accuracy isn't exactly the highest). However, according to Bo (I have not bothered personally investigating this) on precisely those same targets, g++ allocates bit-fields the other way around. According to you, that means that "no one would use" g++? How do you reconcile that claim with the fact that g++ is one of the most popular compilers targeting those platforms? | rick.c.hodgin@gmail.com: Jul 30 09:00PM -0700
This thought occurred to me: https://groups.google.com/d/msg/alt.astronomy/vL_HAEDMbT8/q930nO4TAAAJ -- Rick C. Hodgin | Mr Flibble <flibbleREMOVETHISBIT@i42.co.uk>: Jul 31 01:16PM +0100
> This thought occurred to me: > https://groups.google.com/d/msg/alt.astronomy/vL_HAEDMbT8/q930nO4TAAAJ Fuck off, spammer. /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," Byrne 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." | rick.c.hodgin@gmail.com: Jul 31 05:27AM -0700
On Friday, July 31, 2020 at 8:16:42 AM UTC-4, Mr Flibble wrote: > > https://groups.google.com/d/msg/alt.astronomy/vL_HAEDMbT8/q930nO4TAAAJ > [Expletive deleted], spammer. > /Flibble You are Leigh Johnston. Not Flibble. Leigh Johnston, I bet you won't read the article. Too much truth for you to handle. You always say, "And Satan invented fossils, yes?" like a parroting child. Well here's a potential answer to your skepticism. But I bet you won't read it because you don't seek the truth. Do you? Cluck cluck cluck cluck. -- Rick C. Hodgin | Juha Nieminen <nospam@thanks.invalid>: Jul 31 12:43PM
> Leigh Johnston, I bet you won't read the article. Too much truth > for you to handle. It's complete fiction which is complete insanity if anybody were to believe it. | rick.c.hodgin@gmail.com: Jul 31 06:32AM -0700
On Friday, July 31, 2020 at 8:44:08 AM UTC-4, Juha Nieminen wrote: > It's complete fiction which is complete insanity if anybody were to believe it. That is definitely one possibility. The scenario answers many questions. It asserts God's design. It asserts our need for a Savior. It aligns with faith, and with what we see, just without the enemy's false narrative, for that enemy has purposes on Earth which are of deception and harm: to steal, kill, destroy. You can trust in God. You cannot trust in that enemy. He lies. God does not lie. Consider these things, Juha. Seek the truth and test the things you know against the narrative. See how many things we've observed with questions today are answered in this scenario. -- Rick C. Hodgin | rick.c.hodgin@gmail.com: Jul 31 06:44AM -0700
> On Friday, July 31, 2020 at 8:44:08 AM UTC-4, Juha Nieminen wrote: > > It's complete fiction which is complete insanity if anybody were to believe it. > That is definitely one possibility. The scenario answers many questions. It asserts God's design. It asserts our need for a Savior. It aligns with faith, and with what we see... Remember, the Bible describes that in the beginning God created everything in seven literal days. But even the things He created were not designed for a one-off use. Everything was designed to be part of a system which moves forward from that point forward. Apple trees were created and they were designed to have seeds within themselves to produce the next generation of trees, and to provide food for the people that would be born. It's not a stretch to recognize that God initially created everything as the Bible describes, and then there is this cycle which goes on after. It even states in Revelation that John saw a new Heaven and a new Earth, for the first Earth had past away, which is a hint of this scenario. Revelation 21 https://www.biblegateway.com/passage/?search=Revelation%2021&version=NIV;KJV 1 Then I saw "a new heaven and a new earth,"for the first heaven and the first earth had passed away, and there was no longer any sea. 2 I saw the Holy City, the new Jerusalem, coming down out of heaven from God, prepared as a bride beautifully dressed for her husband. 3 And I heard a loud voice from the throne saying, "Look! God's dwelling place is now among the people, and he will dwell with them. They will be his people, and God himself will be with them and be their God. 4 'He will wipe every tear from their eyes. There will be no more death' or mourning or crying or pain, for the old order of things has passed away." 5 He who was seated on the throne said, "I am making everything new!" Then he said, "Write this down, for these words are trustworthy and true." 6 He said to me: "It is done. I am the Alpha and the Omega, the Beginning and the End. To the thirsty I will give water without cost from the spring of the water of life. 7 Those who are victorious will inherit all this, and I will be their God and they will be my children. 8 But the cowardly, the unbelieving, the vile, the murderers, the sexually immoral, those who practice magic arts, the idolaters and all liars—they will be consigned to the fiery lake of burning sulfur. This is the second death." The NIV translates it as "sulfur" but the original Greek language uses more words to describe it, which are translated as fire and brimstone: https://biblehub.com/text/revelation/21-8.htm Peter talked about the elements being melted with fervent heat: https://www.biblegateway.com/passage/?search=2+Peter+3%3A10&version=NIV;kjv 10 But the day of the Lord will come as a thief in the night; in the which the heavens shall pass away with a great noise, and the elements shall melt with fervent heat, the earth also and the works that are therein shall be burned up. I contacted someone who is a Christian and a PhD astrophysicist to get their input on this idea, and they would not respond to me after the initial outreach. I don't know why. Even if they concluded it was as errant as you suggest, Juha, I would've expected a "Go away. You're insane" type response. But nothing. So, I post it for people to consider. -- Rick C. Hodgin | Mr Flibble <flibbleREMOVETHISBIT@i42.co.uk>: Jul 31 03:52PM +0100
> That is definitely one possibility. The scenario answers many questions. It asserts God's design. It asserts our need for a Savior. It aligns with faith, and with what we see, just without the enemy's false narrative, for that enemy has purposes on Earth which are of deception and harm: to steal, kill, destroy. > You can trust in God. You cannot trust in that enemy. He lies. God does not lie. > Consider these things, Juha. Seek the truth and test the things you know against the narrative. See how many things we've observed with questions today are answered in this scenario. Fuck off, spammer. /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," Byrne 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." | Mr Flibble <flibbleREMOVETHISBIT@i42.co.uk>: Jul 31 03:53PM +0100
> child. Well here's a potential answer to your skepticism. But I bet > you won't read it because you don't seek the truth. Do you? > Cluck cluck cluck cluck. Fuck off, spammer. /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," Byrne 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." |
Melzzzzz <Melzzzzz@zzzzz.com>: Jul 30 04:11AM
> * pipes > * named pipes > * even signals... memory mapped files... | Jorgen Grahn <grahn+nntp@snipabacken.se>: Jul 30 07:33AM
On Wed, 2020-07-29, Jorgen Grahn wrote: > thread listed many different technologies, but the thing about these > is they are applicable in different situations, for different > problems. And reading closer, Felix Palmen pointed that out already: > What's the "right way" to do it depends on the scenario [...] > and of course, the actual design and purpose of your programs). /Jorgen -- // Jorgen Grahn <grahn@ Oo o. . . \X/ snipabacken.se> O o . | IOP <iop@und.com>: Jul 30 05:33PM
> What's the "right way" to do it depends on the scenario (target > operating systems, languages involved, and of course, the actual design > and purpose of your programs). Thank you. This thread has been very informative. Other posters have referenced the book UNIX Network Programming by Stevens, and it seems like this might also give me an idea of a lot of the content that you mention here. I intend to read that book (so far, I've only read the TOC). But if you had any other suggestions that you thought I should look at, I'd be interested. Thanks - IOP | IOP <iop@und.com>: Jul 30 05:37PM
> Python interpreter in a C++ program, and vice versa, you can implement > new Python modules in C++. This would not be trivial though, and might > mean too tight encapsulation. I've heard this before, but I suppose I don't really understand what means (or how to go about) embedding a python interpreter in C++. In the past I have written some python modules in C++ and C, but that's the only sort of thing I've done in that direction. > Boost.ASIO library (https://en.wikipedia.org/wiki/Asio_C%2B%2B_library). > There is some chance it will be included into the C++ standard at some > point in the future. Thank you! I'll examine Boos.ASIO too. - IOP | IOP <iop@und.com>: Jul 30 05:40PM
> engine and, indeed, you can usually freely add new engines to it, and they > will work with it. You can even write your own UCI chess engine and use it > with that GUI if you want. No need for plugins or dlls or whatever. This sounds like a very interesting example. I looked into the UCI spec a bit and it seems like a lot is passed around using plaintext directly through stdin and stdout. This sounds very interesting, and this is definitely something that I would like to better understand. Fortunately, google shows a wealth of resources concerning UCI and these engines, so perhaps I'll find something that makes sense to me. Thank you - IOP | Jorgen Grahn <grahn+nntp@snipabacken.se>: Jul 30 07:45PM
On Thu, 2020-07-30, IOP wrote: > mention here. I intend to read that book (so far, I've only read the > TOC). But if you had any other suggestions that you thought I should > look at, I'd be interested. Eric S. Raymond The Art of Unix Programming chapter 7: Multiprograming http://www.catb.org/esr/writings/taoup/html/multiprogramchapter.html Note that he's defending what he thinks are classic Unix paradigms, so a lot of people probably disagree with him. /Jorgen -- // Jorgen Grahn <grahn@ Oo o. . . \X/ snipabacken.se> O o . | Frederick Gotham <cauldwell.thomas@gmail.com>: Jul 30 02:09AM -0700
This week I'm working on two different products that link with the same library, however one product links with a newer version of the library. The older library has a struct like this: typedef struct { u16 scale; u8 window; u8 a; u8 b; u8 c; float x; float y; float z; u32 reserved[4]; } Manager; And the newer library has the same struct like this: typedef struct { u16 scale; u8 window; u8 a; u8 b; u8 c; float x; float y; float z; s8 offset; u8 transparent : 1; u8 reserved0 : 7; u8 reserved1[2]; u32 reserved2[3]; } Manager; I want to set the member "transparent" on both platforms, and so I started out with code like this: void Set_Flag_For_Transparency(Manager &e) { float *const p_z = &e.z; u8 *const p_offset = reinterpret_cast<u8*>(p_z + 1u); u8 *const p_byte_containing_transparent = p_offset + 1u; *p_byte_containing_transparent |= 0x80; //Set the high bit } After doing a little reading up on bitfields, it seems that ISO/ANSI standards give compilers a lot of freedom as to how bitfields are implemented -- so much freedom in fact that they don't have much use in portable code. For example, in my function just above, the 'transparent' bit might be 0x80 or it might be 0x01. Bits might not straddle bytes, and really the only thing that's guaranteed is the number of bits of precision (e.g. if it's 3 bits then the max value is 7). Are bitfields pretty much useless other than for limiting the max value of an integer type (e.g. 3 bits for 7, 4 bits for 15, 5 bits for 31)? The people who wrote the library I'm working with either: (A) Expect me to use the same compiler as them (B) Expect me to use a compiler that implements bitfields the same way (C) Don't know that bitfields aren't portable for this purpose | Bo Persson <bo@bo-persson.se>: Jul 30 11:36AM +0200
On 2020-07-30 at 11:09, Frederick Gotham wrote: > (A) Expect me to use the same compiler as them > (B) Expect me to use a compiler that implements bitfields the same way > (C) Don't know that bitfields aren't portable for this purpose or (D) Don't use an older library when there is an new and improved one Note that the ISO standard doesn't require a compiler to have 8, 16, or 32 bit integer types, and doesn't say what size a float is. Or if there are padding between members. So this is totally non-portable anyway. And it definitely doesn't give any meaning to reinterpret_cast<u8*>(p_z + 1u) so don't do that. The only portable way to set the transparent bit is e.transparent = 1; If you just *have* set a byte in the reserved area, you could do #if defined SOME_OLD_SYSTEM e.reserved[0] = transparent_hack_value;
<iop@und.com>: Jul 29 05:49AM
I'm trying to understand interprocess communication in a better way. Suppose that I had some C++ program running, and perhaps some python or rust or whatnot program running that is to pass information to the C++ program, and receive information from the C++ program. What is the right way to do this? I believe that sockets might be the answer. Is there a good resource to learn about these sockets with C++ in mind? Thanks, IOP | Marcel Mueller <news.5.maazl@spamgourmet.org>: Jul 29 08:45AM +0200
> rust or whatnot program running that is to pass information to the C++ > program, and receive information from the C++ program. What is the right > way to do this? There is no "right way". There is a way adequate to the specific requirements. Furthermore IPC is not in the scope of a programming language. Especially not if you want to cross language (i.e. runtime library) boundaries. IPC is always platform dependent. Even in case of simple files they might be part of the language but the synchronization for access is not. > I believe that sockets might be the answer. Is there a good resource to > learn about these sockets with C++ in mind? AFAIK the C++ standard never covered sockets. You need to use a platform specific library if you want to use sockets for IPC. But there are other options too. E.g. pipes (sometimes also called fifos). They can be accessed mostly like normal files. Marcel | felix@palmen-it.de (Felix Palmen): Jul 29 08:53AM +0200
> rust or whatnot program running that is to pass information to the C++ > program, and receive information from the C++ program. What is the right > way to do this? There are numerous ways for processes to communicate with each other, for example (in no specific order and probably incomplete) * local/Unix sockets * TCP sockets * SYSV/POSIX message queues * SYSV/POSIX shared memory * pipes * named pipes * even signals... What's the "right way" to do it depends on the scenario (target operating systems, languages involved, and of course, the actual design and purpose of your programs). -- Dipl.-Inform. Felix Palmen <felix@palmen-it.de> ,.//.......... {web} http://palmen-it.de {jabber} [see email] ,//palmen-it.de {pgp public key} http://palmen-it.de/pub.txt // """"""""""" {pgp fingerprint} A891 3D55 5F2E 3A74 3965 B997 3EF2 8B0A BC02 DA2A | Paavo Helde <eesnimi@osa.pri.ee>: Jul 29 10:59AM +0300
> rust or whatnot program running that is to pass information to the C++ > program, and receive information from the C++ program. What is the right > way to do this? In principle this does not require multiple processes. One can embed Python interpreter in a C++ program, and vice versa, you can implement new Python modules in C++. This would not be trivial though, and might mean too tight encapsulation. > I believe that sockets might be the answer. Is there a good resource to > learn about these sockets with C++ in mind? HTTP connections over network sockets (and REST API-s in particular) is indeed a popular way for interprocess communication. It allows for extra flexibility in that the processes may reside on different computers (or in different VM-s or containers, nowadays). In C++ you can implement both an the server and client sides via the Boost.ASIO library (https://en.wikipedia.org/wiki/Asio_C%2B%2B_library). There is some chance it will be included into the C++ standard at some point in the future. So one arguably right way to do interprocess communication is to develop a REST API based on Boost.ASIO library. Depending on your needs this might be an overkill however, if all you want is to send a one-bit notification to the other process, then a POSIX signal or a Windows Event object might do the trick. | Jorgen Grahn <grahn+nntp@snipabacken.se>: Jul 29 08:33AM
> rust or whatnot program running that is to pass information to the C++ > program, and receive information from the C++ program. What is the right > way to do this? Sockets are not the solution to all IPC problems. Others in this thread listed many different technologies, but the thing about these is they are applicable in different situations, for different problems. For example, if you can make the data going between the programs unidirectional, then you don't have to do anything. In a Unix shell: % foo | bar That's also IPC, and it would be foolish to choose sockets if a pipeline would work. > I believe that sockets might be the answer. Is there a good resource to > learn about these sockets with C++ in mind? I learned from W R Stevens' books, but I learned more from "TCP/IP Illustrated" than from the ones about the APIs. /Jorgen -- // Jorgen Grahn <grahn@ Oo o. . . \X/ snipabacken.se> O o . | Juha Nieminen <nospam@thanks.invalid>: Jul 29 10:03AM
> way to do this? > I believe that sockets might be the answer. Is there a good resource to > learn about these sockets with C++ in mind? One prominent example of interprocess communication is what happens between an UCI chess engine and a chess GUI. An UCI chess engine is its own independent command-line program that does nothing else than read commands in human-readable ascii form from stdin, and output results to stdout. In fact, you can run such an engine directly and write commands to it by hand, and it will respond by printing whatever you asked or it's doing. A chess GUI program that supports UCI engines will run such a program as a background process and connect itself to its stdin and stdout streams, and communicate with it in that manner. The advantage of this is that such a GUI program can support any UCI chess engine and, indeed, you can usually freely add new engines to it, and they will work with it. You can even write your own UCI chess engine and use it with that GUI if you want. No need for plugins or dlls or whatever. | "Öö Tiib" <ootiib@hot.ee>: Jul 29 07:44AM -0700
> rust or whatnot program running that is to pass information to the C++ > program, and receive information from the C++ program. What is the right > way to do this? Depends where these programs run and how. I can recommend good book if you are interested about UNIX systems in particular: "UNIX Network Programming, Volume 2: Interprocess Communications", W. Richard Stevens > I believe that sockets might be the answer. Is there a good resource to > learn about these sockets with C++ in mind? Whole internet itself is communication between processes. There are lot of different ways to communicate under different scenarios. Word "sockets" is ambiguous as there are too lot of sockets. Learning tiny subpart of possibilities will take years. For example when the programs that communicate are designed *always* to run on same system that happens to support shared memory and/or memory mapped files then those (shared memory and memory mapped files) are most efficient in good hands but among most disastrous in clumsy hands. ;) When additionally both programs happen to be written in C++ then Boost.Interprocess is relatively decent library that supports it. | "see.my....@gmail.com" <see.my.homepage@gmail.com>: Jul 29 11:41AM -0700
> What is the right > way to do this? I have noticed that all answers so far focused on the lowest possible level, which is a raw communication channel. Sockets can do that. Pipes can do that. Shared memory can do that, too. But just as you design your program using high-level concepts like objects, classes or containers, instead of raw memory blocks, you might as well raise the level of treatment for interprocess communication. In this analogy, sockets are like raw memory blocks and using sockets is like using malloc. Nobody would suggest using malloc if you need an object-oriented design pattern. It is just not the level of abstraction that is typically needed. I would suggest going for a message-oriented library, because the level of abstraction is higher. Yes, such libraries very likely use sockets internally, but that's not relevant (just as it is not relevant that a particular design pattern ultimately relies on some malloc calls). What is relevant is that you can send *messages* between programs. There are many high-level libraries, some of them multi-platform, some of them multi-language. If you need object-oriented ones, look for CORBA (although some consider it to be outdated) or ICE (https://zeroc.com/products/ice). If you are not obsessive about object-orientation, then HTTP is also an option, with multiple high-level libraries for both C++ and Python. As a shameless plug, I will also recommend YAMI4 (http://www.inspirel.com/yami4), which happens to support both your programming languages. The advantage of all such libraries is that you can be several steps ahead in your development thanks to the high-level of abstraction that is offered. Otherwise, you might end up reinventing the wheels (and bugs) that were already implemented (and debugged) in those libraries. Unless, of course, all you need is to send a single flag, once, between two programs. Which is most likely not the case. -- Maciej Sobczak * http://www.inspirel.com | just me <invalid@invalid.org>: Jul 29 09:43AM +0200
On Wed, 15 Jul 2020 18:52:44 -0700 (PDT) > Good bye. > Thank you, > Amine Moulay Ramdane. Do you remember how often you promised that? I believe you don't read answers to your posts but i just couldn't stop my hands writing that... Tom | Bonita Montero <Bonita.Montero@gmail.com>: Jul 29 09:48AM +0200
> Do you remember how often you promised that? I believe you don't read > answers to your posts but i just couldn't stop my hands writing that... Amine has a split personality. | Real Troll <real.troll@trolls.com>: Jul 29 05:10AM -1000
On 29/07/2020 08:48, Bonita Montero wrote: >> Do you remember how often you promised that? I believe you don't read >> answers to your posts but i just couldn't stop my hands writing that... > Amine has a split personality. You forgot the word "disorder". <https://www.nhs.uk/conditions/personality-disorder/> He's a "White Arab" after all. He uses those words to describe himself. | Bonita Montero <Bonita.Montero@gmail.com>: Jul 29 05:02PM +0200
>> Amine has a split personality. > You forgot the word "disorder". > <https://www.nhs.uk/conditions/personality-disorder/> No, he hasn't a personality disorder, he is bipolar. |
Juha Nieminen <nospam@thanks.invalid>: Jul 28 08:54AM
If I understand correctly, this should be possible in C++11 (and later), but I'm not sure how it's done. std::condition_variable is probably involved, but I don't know how it's used for this. So what I want to do is your typical thread pooling system, like this: - At the start of the program, create n background threads. - These background threads idle until the main thread gives them a task to calculate, at which point the thread performs the task, then informs the main thread that it's done, giving it the result, and then starts idling again until it gets a new task (or, perhaps, if feasible, the main thread may immediately give it a new task as a response.) - The main thread gives tasks for those threads to calculate. To do this, it does the following: * First it gives all the background threads tasks to calculate. * Then it waits for any thread to be done with its task. * When a thread informs it that it's done, the main thread handles the result, and gives that thread a new task. - When all the tasks are done, all the background threads are simply left idling, as new tasks may appear in the future. If that's the case, then the previous step is repeated. Could someone give a quick tutorial of how this is done? | Paavo Helde <eesnimi@osa.pri.ee>: Jul 28 01:40PM +0300
28.07.2020 11:54 Juha Nieminen kirjutas: > idling, as new tasks may appear in the future. If that's the case, then > the previous step is repeated. > Could someone give a quick tutorial of how this is done? In C++ there are lambdas, std::async, std::promise and std::future. std::async may use or not use a thread pool internally, as far as I have understood. Googling suggests probably not. On the other hand, creating a new thread for each task would mean significant overhead if the tasks are small. The tasks to be computed are best constructed by lambdas. The lambda syntax allows to prescribe easily which captured variables are copied and which are referenced, this is important for thread-safety. If you want to create your own explicit thread pool, this is IMO best organized by a message queue. The needed jobs are posted in the queue. N worker threads are all waiting on the queue, when a new job arrives one of them will extract it and process it, then goes back to wait on the queue. The queue can be easily built on top of a std::deque<std::function>, std::mutex and std::condition_variable. I'm sure there are also non-blocking variants possible for very high performance needs. The thread pool would replace the std::async part; other parts could still use the same components (lambdas, std::promise, std::future). cppreference.com has some examples. My own thread pool implementations predate c++11, so I'm not so familiar with std::promise and std::future, but in a new implementation I would probably try to use them. | Jorgen Grahn <grahn+nntp@snipabacken.se>: Jul 28 12:41PM
On Tue, 2020-07-28, Paavo Helde wrote: >> but I'm not sure how it's done. std::condition_variable is probably >> involved, but I don't know how it's used for this. >> So what I want to do is your typical thread pooling system, like this: ... >> Could someone give a quick tutorial of how this is done? ... > of them will extract it and process it, then goes back to wait on the > queue. The queue can be easily built on top of a > std::deque<std::function>, std::mutex and std::condition_variable. It would have been nice if there was a std message queue, not just the building blocks needed. Not because it's hard to write one, but to encourage that way of communicating with threads. It's not the /only/ way, but a good default mechanism. Not that I'm an expert on threads or anything. /Jorgen -- // Jorgen Grahn <grahn@ Oo o. . . \X/ snipabacken.se> O o . | Juha Nieminen <nospam@thanks.invalid>: Jul 28 06:23PM
> If you want to create your own explicit thread pool, this is IMO best > organized by a message queue. That gives me the idea for the project I'm thinking that, indeed, maybe it's easier if the threads themselves just find out by themselves what is the next task to perform (in this case they all do the same kind task, just with different parameters). The only thing I need to figure out is to have the threads idle until the main thread has written the required parameters to a common struct and then notify all the threads to start taking tasks from there. Then I also need to figure out how to make the threads notify the main thread when all the tasks are done. I wonder if this should be done with std::future or with std::condition_variable. | Paavo Helde <eesnimi@osa.pri.ee>: Jul 28 10:51PM +0300
28.07.2020 21:23 Juha Nieminen kirjutas: > it's easier if the threads themselves just find out by themselves what > is the next task to perform (in this case they all do the same kind task, > just with different parameters). Well, that's what the queue is about. The worker thread finds out its task by extracting an entry from the queue. > The only thing I need to figure out is to have the threads idle until > the main thread has written the required parameters to a common struct > and then notify all the threads to start taking tasks from there. For each task, the main thread would fill out a struct with parameters, pushes it into the queue under a mutec lock and call conditionvar.notify_one(). Each worker thread would lock the queue mutex and call conditionvar.wait() (which unlocks the mutex behind the scenes while waiting). When the wait call returns, the worker thread checks if there is something in the queue (as there can be spurious wakeups), if so, pops a task from the queue and releases the mutex. That's it. > main thread when all the tasks are done. > I wonder if this should be done with std::future or with > std::condition_variable. This can be done by another queue (containing another mutex and another condition variable). When ready, each thread would push the result to the result queue and notify its condition variable. The main thread waits on this condition variable, when notified, extracts the result from the queue, puts it into the right place and increments the result count. When all results are received, it stops waiting. Your aim is to minimize the time spent under mutex locks when pushing/popping queues. This can be achieved by using move or swap in those operations. Queue-based thread synchronization is great in that only these cheap move/swap operations need to be protected, and otherwise the threads can run by their own without any need to worry about MT safety or synchronization. |
Ben Bacarisse <ben.usenet@bsb.me.uk>: Jul 27 01:05AM +0100
> Yes, sure - but are these systems using function stack frames that are > allocated in lumps from the heap for each function call, or are they > using conventional stacks? The choice is more between allocating them on the heap for each function call or statically allocating one for each function. If the compiler can determine that it's safe (basically no recursive re-entry) the register save and parameter space can be a statically allocated block. <cut> -- Ben. | Bonita Montero <Bonita.Montero@gmail.com>: Jul 27 07:38AM +0200
For what do you need this ability to decide whether an object has been allocated on the stack or the heap ? I don't see any sense in this. | "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com>: Jul 26 11:13PM -0700
On 7/26/2020 10:38 PM, Bonita Montero wrote: > For what do you need this ability to decide whether an object has been > allocated on the stack or the heap ? I don't see any sense in this. Sorry for interjecting, however, imvho, this is an interesting question. There is a way to create a full blown memory allocator using memory on threads stacks only. | "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com>: Jul 26 11:15PM -0700
On 7/26/2020 11:13 PM, Chris M. Thomasson wrote: > Sorry for interjecting, however, imvho, this is an interesting question. > There is a way to create a full blown memory allocator using memory on > threads stacks only. In my case I did not care if where the memory came from. If a thread frees something it did not itself create, well, it would use an atomic XCHG, or CAS. The creator thread, in other words, the one that allocated, would never die until all of its allocations were deallocated. It used a little "fancy" pointer stealing to store a little meta data in the atomic pointer swaps. Iirc, it was only a bit. | Bonita Montero <Bonita.Montero@gmail.com>: Jul 27 08:16AM +0200
> Sorry for interjecting, however, imvho, this is an interesting question. > There is a way to create a full blown memory allocator using memory on > threads stacks only. That's possible without what the OP wanted. Simply open your own heap -arena on the stack with alloca and divide it into smaller parts after- wards. But that's also useless. | Bonita Montero <Bonita.Montero@gmail.com>: Jul 27 08:25AM +0200
I just had the idea that the in_our_stack could be applied to the this pointer on construction and thereby detemining if the object has been allocated on the stack or heap. Something like this: #include <intrin.h> inline bool in_our_stack( void *addr ) { void *stackBottom, *stackTop; #if defined _MSC_VER #if defined(_M_IX86) stackBottom = (void *)__readfsdword( 0x08 ); stackTop = (void *)__readfsdword( 0x04 ); #elif defined(_M_X64) stackBottom = (void *)__readgsqword( 0x10 ); stackTop = (void *)__readgsqword( 0x08 ); #else #error "unsupported MSC-CPU"
| | |