- Change one function pointer in Vtable - 20 Updates
- ::errno - 5 Updates
David Brown <david.brown@hesbynett.no>: Jun 08 07:52PM +0200 On 08/06/2020 19:36, Manfred wrote: > Actually, an interrupt handler is exactly the purpose that volatile is > designed for: it tells the compiler that a variable may change its value > outside the flow of operation as seen by the compiler. Exactly. "Atomic" would be slightly inappropriate (though it would probably work fine here). > However, I am not totally with David Brown on preferring a conditional > to a function pointer - of course it depends on the specific case, and > it may be a matter of taste. Of course it can vary by detail of the case, and personal preference. As a general rule, I usually choose a conditional or switch rather than a function pointer because it gives the compiler far more information for optimisation purposes, and it makes it much easier to follow the flow of the code when reading it, generating call graphs, etc. If your code has no function pointers (or none of a particular type), then it's easy to find every part of your code that calls the function "foo" - you just search for all calls to "foo". If "foo" might have been assigned to a function pointer, such searches are a lot more complicated. It does come at the cost that it can lead to more inter-dependencies between modules that could be avoided by function pointers and call-backs, so there are pros and cons. But since the OP is talking about interrupts, I'm assuming it will be a low-level program and probably fairly small, so I'd start with a variable and conditionals until convinced function pointers are better. |
Keith Thompson <Keith.S.Thompson+u@gmail.com>: Jun 08 11:03AM -0700 >> DO NOT DO THIS -- IT IS UNDEFINED BEHAVIOUR *AT BEST*. > All C++-compilers handle vtables in a similar way. > If you stick to one implementation that's quite manageable. The OP wants to alter which function is called with a given name. Isn't that exactly what function pointers are for? Even if the language guaranteed the behavior of vtables (or mentioned them at all!), what would be the advantage of modifying a vtable rather than using a function pointer? -- 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 */ |
Scott Newman <scott69@gmail.com>: Jun 08 08:07PM +0200 > Even if the language guaranteed the behavior of vtables (or mentioned > them at all!), what would be the advantage of modifying a vtable > rather than using a function pointer? You won't have to deal with implementing your own vtable structure. |
James Kuyper <jameskuyper@alumni.caltech.edu>: Jun 08 02:26PM -0400 On 6/8/20 12:43 PM, Scott Newman wrote: > Of course you can customize the vtable this way. The kind of type-punning needed to do anything like this has undefined behavior. This means, for instance, that an implementation is free to cache vtable pointer somewhere and continue using the cached version, even after you've changed the one in memory. However, the opportunities for something to go wrong are much worse than that. |
James Kuyper <jameskuyper@alumni.caltech.edu>: Jun 08 02:27PM -0400 On 6/8/20 1:20 PM, Scott Newman wrote: >> DO NOT DO THIS -- IT IS UNDEFINED BEHAVIOUR *AT BEST*. > All C++-compilers handle vtables in a similar way. > If you stick to one implementation that's quite manageable. They're not required to do so, and I'd be surprised (or more accurately, astounded) if they all did it in exactly the same way. |
James Kuyper <jameskuyper@alumni.caltech.edu>: Jun 08 02:28PM -0400 On 6/8/20 2:07 PM, Scott Newman wrote: >> them at all!), what would be the advantage of modifying a vtable >> rather than using a function pointer? > You won't have to deal with implementing your own vtable structure. At the cost of having to determine what the implementation's vtable structure is, and at the cost of rendering the behavior of your program undefined. An ordinary function pointer is a far better way of implementing this. |
Scott Newman <scott69@gmail.com>: Jun 08 08:32PM +0200 > structure is, and at the cost of rendering the behavior of your program > undefined. An ordinary function pointer is a far better way of > implementing this. No, you will get an integration of your own functions in the vtable and not a single function-pointer for each function in the object. That's a lot less space. And usually you stay with one implementation where this is reliable. |
Scott Newman <scott69@gmail.com>: Jun 08 08:32PM +0200 > They're not required to do so, and I'd be surprised (or more > accurately, astounded) if they all did it in exactly the same way. The way is still the same since cfront for all C++-compilers. |
Scott Newman <scott69@gmail.com>: Jun 08 08:34PM +0200 > The kind of type-punning needed to do anything like this has undefined > behavior. Doesn't matter if you stay with one impementation. The OP is talking about interrupt-handlers, so it's very unlikely that he needs code that is portable across all compilers. |
Paavo Helde <eesnimi@osa.pri.ee>: Jun 08 09:47PM +0300 08.06.2020 21:03 Keith Thompson kirjutas: >> If you stick to one implementation that's quite manageable. > The OP wants to alter which function is called with a given name. > Isn't that exactly what function pointers are for? In C, yes. C++ provides better means to achieve the same, namely virtual functions, functors and lambdas. In this scenario virtual functions are not applicable, so one could use a functor (a std::function variable), which can be easily assigned by using a lambda. However, if the repertoire of functions involved is small and fixed (as I suspect is the case in this scenario), a simple state variable might appear more readable and maintainable. But this depends on the usage details. > Even if the language guaranteed the behavior of vtables (or mentioned > them at all!), what would be the advantage of modifying a vtable > rather than using a function pointer? I have come to a conclusion there is almost no usage case for plain function pointers in C++. Nearly always one also wants to pass extra data which can be done very conveniently with a lambda. |
Paavo Helde <eesnimi@osa.pri.ee>: Jun 08 09:53PM +0300 08.06.2020 21:32 Scott Newman kirjutas: > and not a single function-pointer for each function in the object. > That's a lot less space. > And usually you stay with one implementation where this is reliable. Until the next compiler version or an innocent compilation flag will optimize away or otherwise break your undefined behavior. C++ does not have a shortage of ways how to shoot yourself in foot inadvertently. There is no reason to do the same intentionally. |
Mr Flibble <flibbleREMOVETHISBIT@i42.co.uk>: Jun 08 07:55PM +0100 On 08/06/2020 19:34, Scott Newman wrote: > Doesn't matter if you stay with one impementation. The OP is talking > about interrupt-handlers, so it's very unlikely that he needs code > that is portable across all compilers. You are manifesting a combination of the two greatest evils: obtuseness and wrongness. How many times have you been fired from your job out of interest? /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." |
Scott Newman <scott69@gmail.com>: Jun 08 08:58PM +0200 >> And usually you stay with one implementation where this is reliable. > Until the next compiler version or an innocent compilation flag will > optimize away or otherwise break your undefined behavior. That'S very unlikely with such a basic feature. |
Scott Newman <scott69@gmail.com>: Jun 08 09:01PM +0200 > You are manifesting a combination of the two greatest evils: obtuseness > and wrongness. How many times have you been fired from your job out of > interest? I have been working as a developer for a long time. And my bosses were always happy with my job. There have never been any problems with my programming style. But you are a theoretician who has nothing to do with practice. |
James Kuyper <jameskuyper@alumni.caltech.edu>: Jun 08 03:01PM -0400 On 6/8/20 2:32 PM, Scott Newman wrote: >> They're not required to do so, and I'd be surprised (or more >> accurately, astounded) if they all did it in exactly the same way. > The way is still the same since cfront for all C++-compilers. How many different implementation of C++ have you actually verified that assumption for? Please list them. |
Scott Newman <scott69@gmail.com>: Jun 08 09:04PM +0200 >> The way is still the same since cfront for all C++-compilers. > How many different implementation of C++ have you actually verified that > assumption for? Please list them. It's just the most obvious way to do it like Cfront. And there is no reason to do it differently. And with all compilers for Windows it is even more important to do it that way because COM is based on this vtable layout; other component-object-models handle it similary. |
James Kuyper <jameskuyper@alumni.caltech.edu>: Jun 08 03:07PM -0400 On 6/8/20 2:34 PM, Scott Newman wrote: > Doesn't matter if you stay with one impementation. The OP is talking > about interrupt-handlers, so it's very unlikely that he needs code > that is portable across all compilers. If the one implementation you're doing it with is one of the ones that takes advantage of the fact that it has undefined behavior to do something you didn't think it could do, no, you can't do that. Please note that it's not sufficient to simply experiment and verify that it works. If the implementation doesn't provide any guarantees about what the behavior will be if you do something like this, it's entirely possible that it will appear to work in every situation you think of testing, but will fail in a situation that you didn't think to test, possibly for reasons that you completely failed to imagine could be relevant. Please cite for me at least one implementation of C++ that provides guarantees about what would happen if your code modifies the vtable, and please tell us precisely what it guarantees about that behavior. |
Scott Newman <scott69@gmail.com>: Jun 08 09:09PM +0200 > If the one implementation you're doing it with is one of the ones that > takes advantage of the fact that it has undefined behavior to do > something you didn't think it could do, no, you can't do that. The whole thing is predictable since no compiler behaves differently than cfront. |
Paavo Helde <eesnimi@osa.pri.ee>: Jun 08 10:11PM +0300 08.06.2020 21:58 Scott Newman kirjutas: >> Until the next compiler version or an innocent compilation flag will >> optimize away or otherwise break your undefined behavior. > That'S very unlikely with such a basic feature. UB is a bug, not a feature. |
Scott Newman <scott69@gmail.com>: Jun 08 09:12PM +0200 >> That'S very unlikely with such a basic feature. > UB is a bug, not a feature. UB is what the standard says, not the implementation. |
Bonita Montero <Bonita.Montero@gmail.com>: Jun 08 08:09PM +0200 Can ayone here tell me why I can't access errno with the ::-prefix ? |
guinness.tony@gmail.com: Jun 08 11:16AM -0700 On Monday, 8 June 2020 19:09:41 UTC+1, Bonita Montero wrote: > Can ayone here tell me why I can't access errno > with the ::-prefix ? Because errno is defined as a macro. 22.4 Error numbers [errno] 1 The contents of the header <cerrno> are the same as the POSIX header <errno.h>, except that errno shall be defined as a macro. [ Note: The intent is to remain in close alignment with the POSIX standard. — end note ] A separate errno value shall be provided for each thread. |
Bonita Montero <Bonita.Montero@gmail.com>: Jun 08 08:21PM +0200 >> Can ayone here tell me why I can't access errno >> with the ::-prefix ? > Because errno is defined as a macro. I "compiled" just with preprocessing-output and errno is not substituted but stays as errno. |
James Kuyper <jameskuyper@alumni.caltech.edu>: Jun 08 02:59PM -0400 > [ Note: The intent is to remain in close alignment with the POSIX standard. > — end note ] > A separate errno value shall be provided for each thread. What POSIX says is: "Any conflict between the requirements described here and the ISO C standard is unintentional." ... "The symbol errno shall expand to a modifiable lvalue of type int. It is unspecified whether errno is a macro or an identifier declared with external linkage." Section 17.5 paragraph 2 of the C standard lists the macros #defined in <errno.h>, and errno is on that list. It goes on to specify that "errno ... expands to a modifiable lvalue 201) that has type int and thread local storage duration ...". Since the C standard explicitly describes errno as a macro, having it be an "identifier declared with external linkage" would be in conflict with the C standard's. As all such conflicts are explicitly declared to be unintentional, that option presumably is not actually permitted. However, the expansion of errno is allowed to be such an identifier. The wording actually used, however, allows other possibilities, such as # define errno (*__errno_location ()) which is how errno is defined in /usr/include/errno.h on my system. |
Paavo Helde <eesnimi@osa.pri.ee>: Jun 08 10:08PM +0300 08.06.2020 21:21 Bonita Montero kirjutas: >> Because errno is defined as a macro. > I "compiled" just with preprocessing-output and > errno is not substituted but stays as errno. This does not refute the C++ standard (19.4 [errno]): "The contents of the header <cerrno> are the same as the POSIX header <errno.h>, except that errno shall be defined as a macro." In my quick test errno got replaced by (*__errno()). |
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