- c++ problem with dynamic and static object - 12 Updates
Melzzzzz <Melzzzzz@zzzzz.com>: Jul 26 04:29AM > a system with a contiguous stack or not, as long as the system > correctly supports automatic storage allocation and deallocation > in some manner. One way or another as long as it does not have deep recursion... -- current job title: senior software engineer skills: c++,c,rust,go,nim,haskell... press any key to continue or any other to quit... U ničemu ja ne uživam kao u svom statusu INVALIDA -- Zli Zec Svi smo svedoci - oko 3 godine intenzivne propagande je dovoljno da jedan narod poludi -- Zli Zec Na divljem zapadu i nije bilo tako puno nasilja, upravo zato jer su svi bili naoruzani. -- Mladen Gogala |
Scott Newman <scott69@gmail.com>: Jul 26 08:05AM +0200 >> You're apparently not kowning the difference between stack storage and >> heap storage !!! > It is called automatic storage and free store. Now, troll, fuck off. It can be called whatever, hopefully the one using the words knows what it means; but you don't. |
"Öö Tiib" <ootiib@hot.ee>: Jul 25 11:23PM -0700 On Saturday, 25 July 2020 04:10:36 UTC+3, Keith Thompson wrote: > Code that assumes that there's such a thing as "the stack" is likely > to be (a) non-portable to exotic platforms and (b) unnecessarily > low-level. The tool behaves like its "automatic storage" is endless and does outright anything when it overflows. So it is somehow programmer's responsibility to ensure that there is sufficient automatic storage. How can programmer honor those obligations without going unnecessarily low-level? |
aotto1968 <aotto1968@t-online.de>: Jul 26 09:45AM +0200 ok - it seems that "c" and "cP" using the SAME constructor… "c" is using the STACK memory and cP is using the HEAP memory… Question can I overload "new" -> https://www.geeksforgeeks.org/overloading-new-delete-operator-c/ to set a flag that cP was created with new? int MQ_CDECL main(int argc, MQ_CST argv[]) { MqC c; auto cP = new MqC(); cP->ObjLog(); try { MqBufferLC args = {argc, argv}; c.ConfigSetName("MyClient"); c.LinkCreate(&args); c.SendSTART(); c.SendEND_AND_WAIT("HLWO"); std::cout << c.ReadC() << std::endl; } catch (const std::exception& e) { c.ErrorCatch(e); } c.Exit(); } |
David Brown <david.brown@hesbynett.no>: Jul 26 01:02PM +0200 On 26/07/2020 00:31, Keith Thompson wrote: >> somewhat valid. > You're using "standard" here to mean "conventional". Of course the > language standard says nothing about this. Yes. I hope that didn't cause any confusion. > call a function, space for its local variables is allocated > by the equivalent of malloc or new, and returning from a > function deallocates space by the equivalent of free or delete. That's my first group. Such mainframes are ancient systems. They are still some in use - there are perhaps even a few that are still produced. But they are used in critical systems - systems that must work correctly without pause over years or decades. Little completely /new/ software is made for these old systems - primarily code for them would be maintaining or expanding existing code. And the people programming or administrating these machines don't use some code they found off github - the people writing code that runs on these systems /know/ they are doing that. More modern mainframes, based on modern ISAs like Power, x86-64, SPARC, etc., are a different matter. But on these systems you have will typically have conventional stacks. In fact, many new mainframe installations are primarily as hosts for Linux virtual machines, and thus the coding is normal Linux programming with conventional stacks. (Mainframes are not something I work with, so any corrections to what I write would be valued.) > I wouldn't bet against such a mechanism becoming popular again in > the future. C++ code that doesn't go out of its way to depend on > implementation-specific details shouldn't even notice the difference. (I agree that C++ code should not see the details of any differences here, unless it is very specialised for some purpose.) I'd be surprised to see it become popular again. There are potential security and reliability benefits from having function stack frames allocated as separate blocks, as well as the possibility of more efficient use of memory (especially in multi-threaded or coroutine environments). But the costs in efficiency of the code are far from insignificant unless you have dedicated hardware support - and "normal" processors do not have that. You can get most of the benefits of growable stacks on most systems by just using the OS's virtual memory system, which already exist. And if you need something more sophisticated, split stacks offer a better solution than heap-allocated function stack frames. Still, predictions are hard, especially about the future. The computing world has gone from early days of trying out a wide variety of hardware systems, to consolidating on "C friendly" architectures. But as such a high proportion of software these days is written in higher level languages, the details of the underlying architectures have become less and less relevant. So maybe new architectures will change this. > Sometimes you might need to work with a subset implementation and > work around missing features. (I suspect that C subsets are more > common than C++ subsets for such systems.) On some small microcontrollers, automatic storage is implemented primarily as static addresses in ram. To do this, the toolchain has to understand the reentrancy of functions to know that the function (or at least the automatic variables) cannot be "live" more than once at a time. This is done with a combination of compiler extensions to mark functions as reentrant or not (often the default is "not") and whole-program optimisation. Smart optimisation and lifetime analysis lets the compiler/linker overlap these static areas to reduce ram usage. Yes, C is usually used on such systems, rather than C++. But sometimes C++ is used too. And yes, you usually have a variety of limitations and non-conformity. (For C++, for example, you can be confident that exceptions and RTTI are not supported.) Again, the point is that you know you are working on such systems. Conversely, if you don't know that you are writing code for something like this, you are not - and can therefore assume you have a more "normal" target. > duration than for objects allocated via new/malloc. If your code > runs on a system where that isn't true, but the system is still > conforming, your program won't break. Yes. (It's better to be potentially a little less efficient than a little less correct!) > activation frames on a heap. But even if you're certain that your > code will only run on conventional systems, I can't think of any > good reason to make your code rely on those assumptions. It's surely going to be undefined behaviour on all systems? Of course, that doesn't mean it won't work "as expected" on most systems, and you can usually convert the addresses to uintptr_t and do the comparisons. I agree entirely that your code shouldn't be using code like that - it's unlikely to make sense, and isn't necessarily going to be stable. The relationship between source code functions and local variables, and their actual implementation, is very far from obvious with modern optimising compilers. (Implementations of functions like memcpy and memmove can be interested in this sort of thing, but as standard library functions, these implementations get to know more about the system details and can "cheat" as necessary.) > On the other hand, if you're examining object addresses in a > debugger, it's perfectly reasonable to make use of whatever you > know about the system. Yes. > a system with a contiguous stack or not, as long as the system > correctly supports automatic storage allocation and deallocation > in some manner. Agreed. |
Jorgen Grahn <grahn+nntp@snipabacken.se>: Jul 26 01:17PM On Sat, 2020-07-25, Paavo Helde wrote: > should have a special method, e.g. static A::Create() which calls 'new > A' and sets a bit marking that a 'delete' call is needed to destroy it. > A more general approach would use a customizable deleter. My hunch is the OP has a fundamental design error, and if that one is fixed he doesn't need is_on_heap(), a flag in the object, or a custom deleter. Finding out what that error is would be hard, though. But as a rule, if you look at a pointer or reference to an object, you should (as the author) be able to tell, statically, who owns the object. And the owner is responsible for deleting it. This rules out e.g. functions like foo(Bar*), where foo sometimes takes over ownership of the Bar, and sometimes not. Exceptions to that rule are rare IME, and most of those exceptions can be handled with std::shared_ptr. /Jorgen -- // Jorgen Grahn <grahn@ Oo o. . . \X/ snipabacken.se> O o . |
Bo Persson <bo@bo-persson.se>: Jul 26 04:59PM +0200 On 2020-07-26 at 13:02, David Brown wrote: > That's my first group. Such mainframes are ancient systems. They are > still some in use - there are perhaps even a few that are still > produced. The lastest of these ancient systems were introduced at the end of 2019: https://en.wikipedia.org/wiki/IBM_z15_(microprocessor) > work correctly without pause over years or decades. Little completely > /new/ software is made for these old systems - primarily code for them > would be maintaining or expanding existing code. "Expanding" existing code includes adding server support for phone apps and webb services. That's totally new code. And lots of it. I recently worked for a bank, where we were about 500 people doing that. > programming or administrating these machines don't use some code they > found off github - the people writing code that runs on these systems > /know/ they are doing that. True, that. :-) |
Paavo Helde <eesnimi@osa.pri.ee>: Jul 26 06:43PM +0300 26.07.2020 16:17 Jorgen Grahn kirjutas: > But as a rule, if you look at a pointer or reference to an object, you > should (as the author) be able to tell, statically, who owns the > object. And the owner is responsible for deleting it. I suspect he has shared reference counted objects which are accessed via smart pointers. I suspect what he now wants is to have some objects on stack, but he still wants to access them via shared pointers, presumably because all interfaces are using smart pointers. An easy way to solve this would abandon objects on stack. Allocate them on heap always and use smart pointers always. Problem solved. Deal with the lost microseconds on dynamic allocation only when the profiler shows it's a bottleneck there. |
David Brown <david.brown@hesbynett.no>: Jul 26 06:25PM +0200 On 26/07/2020 16:59, Bo Persson wrote: >> produced. > The lastest of these ancient systems were introduced at the end of 2019: > https://en.wikipedia.org/wiki/IBM_z15_(microprocessor) 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? > "Expanding" existing code includes adding server support for phone apps > and webb services. That's totally new code. And lots of it. > I recently worked for a bank, where we were about 500 people doing that. Also, are these running on mainframe OS's directly, or are they on Linux virtual machines (or are they on something else) ? |
Bo Persson <bo@bo-persson.se>: Jul 26 10:14PM +0200 On 2020-07-26 at 18:25, David Brown wrote: > 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 architecture doesn't have doesn't have a dedicated hardware stack pointer, or push, pop, and call instructions (unlike the x86). Software convention uses a register pointing to the current activation record (more like a bp register). The compiler can set aside an area for these records, but it is not really a stack. >> I recently worked for a bank, where we were about 500 people doing that. > Also, are these running on mainframe OS's directly, or are they on Linux > virtual machines (or are they on something else) ? The webserver runs on a Linux partition, but it is not emulated or anything, but compiled for the z hardware. The advantage of running the webserver on the mainframe is that it can communicate with the back office systems and databases extremely fast. No network delays. Technically, everything is virtualized as you first boot z/VM and then start any number of z/OS, Linux, and other subsystems from there. Bo Persson |
David Brown <david.brown@hesbynett.no>: Jul 26 10:42PM +0200 On 26/07/2020 22:14, Bo Persson wrote: > convention uses a register pointing to the current activation record > (more like a bp register). The compiler can set aside an area for these > records, but it is not really a stack. I've worked with PowerPC microcontrollers - while not exactly the same as Power, they share a lot of common ancestry and features. You can say that is no dedicated stack pointer register - or you can say that /any/ GPR register (except 0) is a stack pointer. "Push" and "pop" are just loads and stores with pre- or post- increment and decrement, using whichever "stack pointer" register you want, and with the stack growing upwards or downwards as you choose. "Call" is "branch and link", with non-leaf functions starting with a "push link register" sequence. Local data on the stack can be accessed from the "stack pointer" as just register + index addressing. Any register can be used as an equivalent to the BP on x86. So you can choose to use a stack or not, and can easily have multiple stacks (that would be nice for Forth). The details are left up to the ABI, which is effectively an agreement between the OS, libraries, and compilers. Since I have only used the microcontroller cores, I am only familiar with the 32-bit EABI. There you have r1 dedicated as the "stack pointer" with a conventional downward-growing stack. (There are actually, I think, different variants of the EABI with slightly different details matching different variants of the PPC cores, but AFAIK they all use r1 as a stack pointer.) However, I don't know if this also applies to programming on the Power on zSeries machines. >> virtual machines (or are they on something else) ? > The webserver runs on a Linux partition, but it is not emulated or > anything, but compiled for the z hardware. That is what I thought. (No need to emulate it when it is a supported processor type!) > The advantage of running the > webserver on the mainframe is that it can communicate with the back > office systems and databases extremely fast. No network delays. There will be many other advantages too, as compared to running Linux on bog-standard x86 boxes (or even a Talos II Power-based server). You get hot-plug and hot-replacement of everything, including cpus and ram, and huge scalability. I have also read of records for the speed at which new Linux partitions can be installed on these things. > Technically, everything is virtualized as you first boot z/VM and then > start any number of z/OS, Linux, and other subsystems from there. OK, so z/OS is a guest OS, just like Linux? And the virtualisation is of the level of, say, VMWare, VirtualBox or KVM, rather than emulation like QEMU or "super chroot jail" like Linux Containers, Docker, or Solaris Zones ? That is to say, each partition (if that is the correct term) has its own kernel, with hardware interaction being handled by the hypervisor (z/VM)? (I'm sorry, this is getting a bit off-topic for this group, but it's nice to learn a little from someone who has used these things.) |
Manfred <invalid@add.invalid>: Jul 27 12:33AM +0200 On 7/26/20 9:45 AM, aotto1968 wrote: > Question can I overload "new" > -> https://www.geeksforgeeks.org/overloading-new-delete-operator-c/ > to set a flag that cP was created with new? AFAIK you can't. Overloading operator new is obviously possible, but in the overload you only have access to the raw memory of the object, /before/ the constructor is run, and you cannot pass arguments to the constructor from there - it is an allocation function, the constructor is called by the language. |
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