- Change one function pointer in Vtable - 14 Updates
- [Jesus Loves You] Tag for filtering - 3 Updates
- Scott Newman - 2 Updates
"Chris M. Thomasson" <chris.m.thomasson.1@gmail.com>: Jun 09 11:53AM -0700 On 6/9/2020 11:20 AM, Scott Newman wrote: >>> as an atomic<bool>. >> EVERYTHING YOU SAY IS WRONG. > Wrong. Try to create a proper attribution? |
James Kuyper <jameskuyper@alumni.caltech.edu>: Jun 09 02:57PM -0400 On 6/9/20 10:23 AM, Scott Newman wrote: ... >> However, I'm far more reliable when I say "I see a problem" than when I >> say "I see no problems". > You shoudn't be a programmer. OK - lack of justification noted. |
Scott Newman <scott69@gmail.com>: Jun 09 08:58PM +0200 >>> EVERYTHING YOU SAY IS WRONG. >> Wrong. > Try to create a proper attribution? Why ? I can see from the thread wo were those that have spoken before. |
"Chris M. Thomasson" <chris.m.thomasson.1@gmail.com>: Jun 09 12:03PM -0700 On 6/8/2020 9:54 AM, Scott Newman wrote: > will take the this pointer. > There might be implementations where this won't work, but > currently there isn't any. Humm... How do you access the vtable in a 100% portable manner? Some compilers might keep a pointer to the table in front of everything. So, this points minus offset to get at the pointer. What if the pointer is constant and points to a static array? http://codepad.org/SJvF3Y3v from the following thread: https://groups.google.com/d/topic/comp.lang.c/JNl51a9nibs/discussion ______________________________ #include <stdio.h> #include <stdlib.h> /* "SysCall" Interface ___________________________________________________________*/ typedef int (*fp_syscall_type) (void*, void*); #define syscall_explicit(mp_obj, mp_fidx, mp_ctx) ( \ (mp_obj)->vtable->fp[(mp_fidx)]((mp_obj), (mp_ctx)) \ ) /* Sample Device Object Interface ___________________________________________________________*/ enum device_vtable_fidx { DEVICE_FIDX_DESTROY = 0, DEVICE_FIDX_READ = 1, DEVICE_FIDX_WRITE = 2 }; struct device_vtable { fp_syscall_type fp[3]; }; struct device_ctx { void* buf; size_t bufsz; }; struct device { struct device_vtable const* vtable; }; #define device_destroy(mp_obj) \ syscall_explicit(mp_obj, DEVICE_FIDX_DESTROY, NULL) #define device_read(mp_obj, mp_ctx) \ syscall_explicit(mp_obj, DEVICE_FIDX_READ, mp_ctx) #define device_write(mp_obj, mp_ctx) \ syscall_explicit(mp_obj, DEVICE_FIDX_WRITE, mp_ctx) /* Sample USB Device Interface ___________________________________________________________*/ extern int usb_drive_create(struct device**); /* Sample USB Drive Impl ___________________________________________________________*/ struct usb_drive_impl { struct device iface; /* usb drive specific stuff */ }; static int usb_drive_syscall_destroy(void*, void*); static int usb_drive_syscall_read(void*, void*); static int usb_drive_syscall_write(void*, void*); static struct device_vtable const g_device_vtable = {{ usb_drive_syscall_destroy, usb_drive_syscall_read, usb_drive_syscall_write }}; int usb_drive_create( struct device** const self_iface ){ struct usb_drive_impl* self = malloc(sizeof(*self)); if (self) { self->iface.vtable = &g_device_vtable; *self_iface = &self->iface; printf("usb_drive_create(%p)\r\n", (void*)self); return 0; } return 1; } int usb_drive_syscall_destroy( void* self_, void* ctx_ ){ struct usb_drive_impl* const self = self_; free(self); printf("usb_drive_syscall_destroy(%p, %p)\r\n", self_, ctx_); return 0; } int usb_drive_syscall_read( void* self_, void* ctx_ ){ struct usb_drive_impl* const self = self_; struct device_ctx* const ctx = ctx_; printf("usb_drive_syscall_read(%p, %p)\r\n", self_, ctx_); printf("read %lu bytes into %p\r\n", (unsigned long)ctx->bufsz, ctx->buf); return 0; } int usb_drive_syscall_write( void* self_, void* ctx_ ){ struct usb_drive_impl* const self = self_; struct device_ctx* const ctx = ctx_; printf("usb_drive_syscall_write(%p, %p)\r\n", self_, ctx_); printf("write %lu bytes from %p\r\n", (unsigned long)ctx->bufsz, ctx->buf); return 0; } /* Sample Application ___________________________________________________________*/ void read_write( struct device* self ){ char buf[32] = { '\0' }; struct device_ctx dctx = { buf, 16 }; /* Use the device object interface */ device_read(self, &dctx); dctx.bufsz = 8; device_write(self, &dctx); /* Use the device with explicit syscall's */ dctx.bufsz = 24; syscall_explicit(self, DEVICE_FIDX_READ, &dctx); dctx.bufsz = 13; syscall_explicit(self, DEVICE_FIDX_WRITE, &dctx); } int main() { struct device* self = NULL; if (! usb_drive_create(&self)) { read_write(self); device_destroy(self); } return 0; } ______________________________ |
"Chris M. Thomasson" <chris.m.thomasson.1@gmail.com>: Jun 09 12:39PM -0700 On 6/9/2020 11:58 AM, Scott Newman wrote: >>> Wrong. >> Try to create a proper attribution? > Why ? I can see from the thread wo were those that have spoken before. Out of courtesy? Keeping meta data within the post? |
"Chris M. Thomasson" <chris.m.thomasson.1@gmail.com>: Jun 09 12:43PM -0700 On 6/9/2020 3:39 AM, Scott Newman wrote: >> behavior (as we all know by now) and memory leaks. > The memory-leak doen't count because this is only an example of how > it principally works. [...] You are Bonita? This response sounds eerily similar. And/or Gabriel? |
James Kuyper <jameskuyper@alumni.caltech.edu>: Jun 09 03:58PM -0400 On 6/9/20 2:58 PM, Scott Newman wrote: >>> Wrong. >> Try to create a proper attribution? > Why ? I can see from the thread wo were those that have spoken before. See <https://www.ietf.org/rfc/rfc1855.txt>; search for "attribution". I'm sure you won't be convinced, so you don't need to bother looking if you don't want to. |
Vir Campestris <vir.campestris@invalid.invalid>: Jun 09 09:11PM +0100 On 09/06/2020 18:41, Mr Flibble wrote: > EVERYTHING YOU SAY IS WRONG. If it was he'd be really valuable. I don't think he's that reliable. Andy |
Vir Campestris <vir.campestris@invalid.invalid>: Jun 09 09:21PM +0100 On 09/06/2020 15:57, Manfred wrote: >> portable manner. >> volatile is largely obsolete. > Am I wrong? The fun comes with machines that don't follow norms. The vast majority of machines have a symmetric memory architecture and hardware cache coherence. The programmer doesn't have to worry about whether the content of a memory location is see as the same from all CPUs; the caches talk to each other, and make it look like that. But not all. There are systems where when you access a memory location from a CPU it pulls it into the local cache. When another CPU accesses it, it gets pulled into that cache. When one of them writes it - well, that just alters its local cache and the programmer needs to make sure that things get flushed out in the right order when they are shared. That makes for a fast simple cache design, and systems where a dual CPU can be more than twice as fast as a single. I haven't used one for years though. There are also systems where there are a bunch of CPUs all with their own memory, and when you want an address that's in the memory belonging to another CPU it's got to be sent across. I haven't used one of those at all. Now consider the case where an interrupt comes in and is handled by one of the CPUs. It modifies data that another CPU has cached. Just making sure it got to RAM doesn't ensure that the caches are in step with the RAM. Andy |
Vir Campestris <vir.campestris@invalid.invalid>: Jun 09 09:27PM +0100 On 09/06/2020 09:21, Scott Newman wrote: > // volatile to prevent any caching > virtual int CC add( int a, int b ); > }; I won't go through the rest of the program, but only point out that virtual != volatile. That comment is a lie. Andy |
Ben Bacarisse <ben.usenet@bsb.me.uk>: Jun 09 09:49PM +0100 >> -fsanitize=undefined but I am sure opinions vary on that. (Of course it >> may be a bug in the sanitizer, but I don't think so.) > My code is optimized for performance. So compile it with -O3. Same result. It's the sanitizer correctly finding something undefined in the code. I wasn't 100% sure at first because the system detects a segmentation violation before the sanitizer can report the problem. So I ran it under valgrind (which handles the invalid accesses itself) and that allows me to see what it is that -fsanitize=undefined is trying to report: vtab.cc:46:19: runtime error: member call on address 0x00000575cc80 which does not point to an object of type 'S' 0x00000575cc80: note: object has invalid vptr -- Ben. |
James Kuyper <jameskuyper@alumni.caltech.edu>: Jun 09 05:00PM -0400 On 6/9/20 4:27 PM, Vir Campestris wrote: >> }; > I won't go through the rest of the program, but only point out that > virtual != volatile. That comment is a lie. I suspect that the comment is merely misplaced. The "volatile" that it refers to is much farther down in the program: > S *volatile s2 = s; If he's not just a troll, if he honestly believes that it will in fact prevent caching of the vtable pointer, he's only incorrect, not lying. |
James Kuyper <jameskuyper@alumni.caltech.edu>: Jun 09 05:55PM -0400 On 6/9/20 4:21 AM, Scott Newman wrote: > *vtable = (void *)pSub; > *(void **)s = vtable; > } I just noticed a few more problems. First, a minor quibble. Your code assumes that the vtable pointer has a type that uses the same representation as void*; the only type for which that is guaranteed to be the case is char*. There have been real-world systems where pointers to different types of objects had different representations - most commonly, because they had different sizes. I'm quite certain that you'll dismiss this issue as unimportant, if you even acknowledge that it is technically correct. The second issue is more important. Your code is apparently intended to replace the vtable pointer value with a new value that points to a new table. The OP was looking for a way to change one of the entries in the existing table pointed at by that pointer, which would require quite different code. |
James Kuyper <jameskuyper@alumni.caltech.edu>: Jun 09 07:11PM -0400 On 6/9/20 4:21 AM, Scott Newman wrote: ... > int (* CC pSub)( S *, int, int ) = sub; ... > *vtable = (void *)pSub; One more minor quibble: "Converting a function pointer to an object pointer type or vice versa is conditionally-supported. The meaning of such a conversion is implementation-defined, except that if an implementation supports conversions in both directions, converting a prvalue of one type to the other type and back, possibly with different cv-qualification, shall yield the original pointer value." (8.2.10p6). So this supposedly "100% portable" code cannot be ported to systems (and there are some in the real world) that do not support such conversions. On such systems, the only function pointers that are guaranteed convertible to void* are null pointers - which wouldn't be much use in this context. Note that any pointer to a function can be converted to a pointer of any other type and back again, with the result being guaranteed to be equal to the original. Therefore, while void* cannot be portably used for this purpose, any arbitrary pointer to function type could be. I normally use void(*)(void) for such purposes. However, there's no guarantee what type any give implementation uses for it's vtable entries. While any two pointer to function types are required to support round-trip conversions, they are not required to all have the same representations, or even the same size, so it could make a difference. |
Juha Nieminen <nospam@thanks.invalid>: Jun 09 06:53PM > you of His existence and what He offers. > You owe it to yourself and others to investigate it with a > truth-seeking heart. Are you able to comprehend what other people write to you? |
Keith Thompson <Keith.S.Thompson+u@gmail.com>: Jun 09 01:40PM -0700 > rick.c.hodgin@gmail.com wrote: [snip] > Are you able to comprehend what other people write to you? Rick posts with a valid email address. If you feel the need to communicate with him, you can reach him that way. Please don't waste everyone else's time by posting public replies. (I don't see his posts, only followups -- and not all of us choose to filter on strings in subject lines.) In short, please stop feeding the troll. -- 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 */ |
rick.c.hodgin@gmail.com: Jun 09 03:44PM -0700 On Tuesday, June 9, 2020 at 2:53:55 PM UTC-4, Juha Nieminen wrote: > Are you able to comprehend what other people write to you? Of course. But the teaching is there's more to what you think you know than what really exists. There's an enemy at work in this world deceiving people into be- lieving his lies when they only glance at the surface, or only give the real facts a cursory or shallow examination. It's only when you press in seeking the truth for real that you uncover the enemy's lies, and you're able to know the truth. It's all I have to offer you and others, Juha. I fear many of you will only come to realize the truth I've been teaching you on the very day when it will do you no good to come into that information. Today is the day to begin seeking, and to find the truth. None of us are promised tomorrow. -- Rick C. Hodgin |
Vir Campestris <vir.campestris@invalid.invalid>: Jun 09 09:29PM +0100 On 09/06/2020 19:38, Chris M. Thomasson wrote: >> Sorry, but these are really superficial parallels. > Indeed. However, they are fairly similar nonetheless. Just enough to > make one ponder... ;^) I hadn't noticed. Bonita seems far more sane. Andy |
Ian Collins <ian-news@hotmail.com>: Jun 10 08:40AM +1200 On 09/06/2020 06:56, Mr Flibble wrote: > Scott Newman <scott69@gmail.com>. Who the hell is this guy? Is he for real? An obvious and successful troll. Either a Bonita alias or copycat. It amazes that otherwise sensible posters keep responding to both of them. -- Ian. |
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