- void* address of most derived type - 8 Updates
- the smaller prog C++ - 4 Updates
- on main - 4 Updates
- the smaller prog C++ - 8 Updates
- scope resolution operator - 1 Update
"Norman J. Goldstein" <normvcr@telus.net>: Apr 09 09:34PM -0700 Aside from writing virtual methods to do the job, I am wondering whether there is something like type_index/type_info to divulge the (void*) address of the most derived type. On a related question, when restricting to single inheritance, are compilers obliged to have the same (void*) address for each class in the hierarchy? |
Paavo Helde <myfirstname@osa.pri.ee>: Apr 10 12:05AM -0500 "Norman J. Goldstein" <normvcr@telus.net> wrote in news:mg7jt9$b2e$1 > Aside from writing virtual methods to do the job, I am wondering whether > there is something like type_index/type_info to divulge the (void*) > address of the most derived type. As far as I understand you have a pointer to a base class and want to get a pointer to the most derived class, without knowing the most derived class type? That would be dynamic_cast<void*>(...) (assuming you have polymorphic types so dynamic_cast can be used). This works for multiple inheritance as well. > On a related question, when > restricting to single inheritance, are compilers obliged to have the > same (void*) address for each class in the hierarchy? I believe this is not guaranteed, but will probably work in practice with most compilers, at least when all classes are of the same type (polymorphic or not polymorphic). hth Paavo |
"Öö Tiib" <ootiib@hot.ee>: Apr 10 12:48AM -0700 On Friday, 10 April 2015 07:35:00 UTC+3, Norman J. Goldstein wrote: > Aside from writing virtual methods to do the job, I am wondering whether > there is something like type_index/type_info to divulge the (void*) > address of the most derived type. You must have pointer to non-virtual base class to find out most derived type with 'typeid(*ptr)'; 'void' is not base class. If you know exactly from pointer to what type you did cast implicitly or with 'static_cast' to 'void*' then you can 'static_cast' it back. If you 'dynamic_cast<void*>' then you get address of most non-virtually derived object, that is actually not what you want unless you exactly know the type. > On a related question, when > restricting to single inheritance, are compilers obliged to have the > same (void*) address for each class in the hierarchy? On case of single *and* non-virtual inheritance such classes in practice usually have same address but it is not guaranteed. The practice is because of required order of initialization and required implicit casts and finding vtable location (existence of what is not guaranteed at all) are likely cheaper to implement. On case of virtual inheritance the address is not same usually. Virtual inheritance is most expensive and tricky. Introducing it into language was likely mistake, but I don't care since I never use it. On case of multiple inheritance the different base subobjects can not be at same address by simple logic. Generally it is better to avoid casting. If you really need to then consider making some special functions or member functions that do it. It is easier to instrument such function with debug checks and breakpoints. |
"Norman J. Goldstein" <normvcr@telus.net>: Apr 10 01:15AM -0700 I wrote a test routine, and it does exactly as you say. Many thanks. On 04/09/2015 10:05 PM, Paavo Helde wrote: >> there is something like type_index/type_info to divulge the (void*) >> address of the most derived type. > As far as I understand you have a pointer to a base class and want to get a |
"Norman J. Goldstein" <normvcr@telus.net>: Apr 10 01:30AM -0700 On 04/10/2015 12:48 AM, Öö Tiib wrote: > If you 'dynamic_cast<void*>' then you get address of most > non-virtually derived object, that is actually not what you want > unless you exactly know the type. On gcc 4.8, the dynamic_cast<void*> is doing the right thing, whether the most derived object is virtually derived, or not (according to my test routine). Why do you think virtual derivation could make a difference? |
"Öö Tiib" <ootiib@hot.ee>: Apr 10 01:59AM -0700 On Friday, 10 April 2015 11:30:21 UTC+3, Norman J. Goldstein wrote: > On gcc 4.8, the dynamic_cast<void*> is doing the right thing, whether > the most derived object is virtually derived, or not (according to my > test routine). Why do you think virtual derivation could make a difference? Sorry, I read it over and I did remember/know it incorrectly. 'dynamic_cast'ing from virtual base pointer to most derived type pointer and 'dynamic_cast'ing from virtual base pointer to 'void*' must give same address. That is address of most derived object. Avoiding a feature because of its inefficiency and avoiding other feature because of its fragility apparently may result with misremembering how those overlap. |
"Norman J. Goldstein" <normvcr@telus.net>: Apr 10 09:53AM -0700 On 04/10/2015 01:59 AM, Öö Tiib wrote: > Avoiding a feature because of its inefficiency and avoiding other feature > because of its fragility apparently may result with misremembering how > those overlap. Thanks for checking! |
Paavo Helde <myfirstname@osa.pri.ee>: Apr 10 02:06PM -0500 嘱 Tiib <ootiib@hot.ee> wrote in > Avoiding a feature because of its inefficiency and avoiding other > feature because of its fragility apparently may result with > misremembering how those overlap. Inefficiency is always relative. There are lots of usage cases where the speed is not so critical. For example I have used dynamic_cast quite successfully in some MFC-based projects (working around MFC design deficiences via multiple derivation and dynamic_casting between my and MFC class hierarchy trees). Worked pretty well actually, at least when compared to the rest of the MFC mess. Cheers Paavo |
ram@zedat.fu-berlin.de (Stefan Ram): Apr 10 02:20PM >>>>(Below, I use »N« for an end-of-line symbol in the source code.) #include<iostream.h>N#include<bitset.h>Nint x;main(){bitset<16>a[]={21845,13107,3855,255};while(x<4)cout<<a[x++]<<"\n";} #include<iostream>Nint main(){std::cout<<"0101010101010101\n0011001100110011\n0000111100001111\n0000000011111111\n";} #include<iostream>Nint main(){for(int i=0;i<4;++i){for(int j=0;j<16;++j)std::cout<<j/(1<<i)%2;std::cout<<'\n';}} #include<stdio.h>Nint main(){for(int i=0;i<4;++i){for(int j=0;j<16;++j)putchar('0'+j/(1<<i)%2);puts("");}} #include<stdio.h>Nint main(){int i,j;for(i=0;i<4;++i,puts(""))for(j=0;j<16;++j)putchar('0'+j/(1<<i)%2);} #include<stdio.h>Nint main(){int i=0,j;for(;i<4;++i,puts(""))for(j=0;j<16;++j)putchar('0'+j/(1<<i)%2);} (Nonportably, »'0'« might be replaced by »48«, and often »stdio.h« can be replaced by »cstdio«.) |
ram@zedat.fu-berlin.de (Stefan Ram): Apr 10 02:33PM >>>>>(Below, I use »N« for an end-of-line symbol in the source code.) #include<iostream.h>N#include<bitset.h>Nint x;main(){bitset<16>a[]={21845,13107,3855,255};while(x<4)cout<<a[x++]<<"\n";} #include<iostream>Nint main(){std::cout<<"0101010101010101\n0011001100110011\n0000111100001111\n0000000011111111\n";} #include<iostream>Nint main(){for(int i=0;i<4;++i){for(int j=0;j<16;++j)std::cout<<j/(1<<i)%2;std::cout<<'\n';}} #include<stdio.h>Nint main(){for(int i=0;i<4;++i){for(int j=0;j<16;++j)putchar('0'+j/(1<<i)%2);puts("");}} #include<stdio.h>Nint main(){int i,j;for(i=0;i<4;++i,puts(""))for(j=0;j<16;++j)putchar('0'+j/(1<<i)%2);} #include<stdio.h>Nint main(){int i=0,j;for(;i<4;++i,puts(""))for(j=0;j<16;++j)putchar('0'+j/(1<<i)%2);} #include<stdio.h>Nint main(){int i=0,j;for(;i<4;++i,puts(""))for(j=0;j<16;)putchar('0'+j++/(1<<i)%2);} (Nonportably, »'0'« might be replaced by »48«, and often »stdio.h« can be replaced by »cstdio«.) |
ram@zedat.fu-berlin.de (Stefan Ram): Apr 10 02:40PM >If you're going to be pedantic, assuming '1' equals '0'+1 isn't portable >either. »In both the source and execution basic character sets, the value of each character after 0 in the above list of decimal digits shall be one greater than the value of the previous.« - 2.3p3 |
ram@zedat.fu-berlin.de (Stefan Ram): Apr 10 07:05PM >>>>>>(Below, I use »N« for an end-of-line symbol in the source code.) #include<iostream.h>N#include<bitset.h>Nint x;main(){bitset<16>a[]={21845,13107,3855,255};while(x<4)cout<<a[x++]<<"\n";} #include<iostream>Nint main(){std::cout<<"0101010101010101\n0011001100110011\n0000111100001111\n0000000011111111\n";} #include<iostream>Nint main(){for(int i=0;i<4;++i){for(int j=0;j<16;++j)std::cout<<j/(1<<i)%2;std::cout<<'\n';}} #include<stdio.h>Nint main(){for(int i=0;i<4;++i){for(int j=0;j<16;++j)putchar('0'+j/(1<<i)%2);puts("");}} #include<stdio.h>Nint main(){int i,j;for(i=0;i<4;++i,puts(""))for(j=0;j<16;++j)putchar('0'+j/(1<<i)%2);} #include<stdio.h>Nint main(){int i=0,j;for(;i<4;++i,puts(""))for(j=0;j<16;++j)putchar('0'+j/(1<<i)%2);} #include<stdio.h>Nint main(){int i=0,j;for(;i<4;++i,puts(""))for(j=0;j<16;)putchar('0'+j++/(1<<i)%2);} #include<stdio.h>Nint main(){for(int i=0;i<64;i%16?0:puts(""))putchar('0'+i++/(1<<(i>>4))%2);} (Nonportably, »'0'« might be replaced by »48«, and often »stdio.h« can be replaced by »cstdio«.) |
Martin Shobe <martin.shobe@yahoo.com>: Apr 09 06:37PM -0500 On 4/9/2015 3:54 PM, Vir Campestris wrote: >> Not a valid C++ program. > Not valid - or just not compatible with any OS I ever came across? > (Win and *n?x seem to require argc and argv...) Not valid. There are several things, including a type for x and a prototype for printf, that need to be fixed before we talk about the non-standard prototype for main. Martin Shobe |
"Lőrinczy Zsigmond" <nospam@for.me>: Apr 10 06:29AM +0200 > main(x){printf("%x",x);} > Is a valid C++ program > and what number it print... Never hesitate to try it. http://www.thefreecountry.com/compilers/cpp.shtml |
scott@slp53.sl.home (Scott Lurndal): Apr 10 01:50PM >> Not a valid C++ program. >Not valid - or just not compatible with any OS I ever came across? >(Win and *n?x seem to require argc and argv...) *n?x provides argc, argv, envp and auxv. Most programs only use argc, argv, and some use envp as well. There is nothing illegal or undefined about defining main to consume only the argc parameter; the remaining parameters passed by the exec call will be ignored and unavailable to the app (although getenv()/setenv()/putenv() will access the environment directly). auxv, which is passed from the kernel, is often consumed by the run-time-linker/loader and may or may not be provided to the application depending on the OS. As otherwise pointed out, the value of the 'argc' parameter depends on how the main function was invoked. scott |
Robert Wessel <robertwessel2@yahoo.com>: Apr 10 01:34PM -0500 On Fri, 10 Apr 2015 13:50:18 GMT, scott@slp53.sl.home (Scott Lurndal) wrote: >directly). auxv, which is passed from the kernel, >is often consumed by the run-time-linker/loader and may or may >not be provided to the application depending on the OS. There's' nothing preventing an implementation from providing an extension so that a form of main() other than the two specified in the standard are supported, but the form being proposed here is undefined per the standard. Yes, with some of the common calling conventions used by C implementations it would work naturally, but that is certainly not required. |
ram@zedat.fu-berlin.de (Stefan Ram): Apr 10 01:59PM >ram@zedat.fu-berlin.de (Stefan Ram) writes: >>>(Below, I use »N« for an end-of-line symbol in the source code.) #include<iostream.h>N#include<bitset.h>Nint x;main(){bitset<16>a[]={21845,13107,3855,255};while(x<4)cout<<a[x++]<<"\n";} #include<iostream>Nint main(){std::cout<<"0101010101010101\n0011001100110011\n0000111100001111\n0000000011111111\n";} #include<iostream>Nint main(){for(int i=0;i<4;++i){for(int j=0;j<16;++j)std::cout<<j/(1<<i)%2;std::cout<<'\n';}} #include<stdio.h>Nint main(){for(int i=0;i<4;++i){for(int j=0;j<16;++j)putchar('0'+j/(1<<i)%2);puts("");}} #include<stdio.h>Nint main(){int i,j;for(i=0;i<4;++i,puts(""))for(j=0;j<16;++j)putchar('0'+j/(1<<i)%2);} (Nonportably, »'0'« might be replaced by »48, and often »stdio.h« can be replaced by »cstdio«.) |
Martijn van Buul <pino@dohd.org>: Apr 10 02:36PM * Stefan Ram: > i=0,j;for(;i<4;++i,puts(""))for(j=0;j<16;++j)putchar('0'+j/(1<<i)%2);} > (Nonportably, »'0'« might be replaced by »48«, and often »stdio.h« can be > replaced by »cstdio«.) If you're going to be pedantic, assuming '1' equals '0'+1 isn't portable either. -- Martijn van Buul - pino@dohd.org |
Victor Bazarov <v.bazarov@comcast.invalid>: Apr 10 10:43AM -0400 On 4/10/2015 10:36 AM, Martijn van Buul wrote: >> replaced by »cstdio«.) > If you're going to be pedantic, assuming '1' equals '0'+1 isn't portable > either. Yes, it most certainly is. See [lex.charset]/3, "...In both the source and execution basic character sets, the value of each character after 0 in the above list of decimal digits shall be one greater than the value of the previous. " In my understanding it means that '1' == '0' + 1, and so on. V -- I do not respond to top-posted replies, please don't ask |
JiiPee <no@notvalid.com>: Apr 10 04:10PM +0100 On 10/04/2015 15:43, Victor Bazarov wrote: > the value of the previous. " > In my understanding it means that '1' == '0' + 1, and so on. > V yes thats my understanding as well. I remember reading from somewhere that is it a rule. |
scott@slp53.sl.home (Scott Lurndal): Apr 10 03:11PM >> replaced by »cstdio«.) >If you're going to be pedantic, assuming '1' equals '0'+1 isn't portable >either. Although it works in all of the BCD, EBCDIC, UTF-8 (ASCII subset) and USASCII codesets. |
Luca Risolia <luca.risolia@linux-projects.org>: Apr 10 05:35PM +0200 On 10/04/2015 16:33, Stefan Ram wrote: > #include<stdio.h>Nint main(){int i,j;for(i=0;i<4;++i,puts(""))for(j=0;j<16;++j)putchar('0'+j/(1<<i)%2);} > #include<stdio.h>Nint main(){int i=0,j;for(;i<4;++i,puts(""))for(j=0;j<16;++j)putchar('0'+j/(1<<i)%2);} > #include<stdio.h>Nint main(){int i=0,j;for(;i<4;++i,puts(""))for(j=0;j<16;)putchar('0'+j++/(1<<i)%2);} maybe short, as required, but not really interesting in C++. Try to produce the whole result in a generic way at compile time instead ;) |
Marcel Mueller <news.5.maazl@spamgourmet.org>: Apr 10 06:16PM +0200 On 10.04.15 16.33, Stefan Ram wrote: >>>>>> (Below, I use »N« for an end-of-line symbol in the source code.) > #include<iostream.h>N#include<bitset.h>Nint x;main(){bitset<16>a[]={21845,13107,3855,255};while(x<4)cout<<a[x++]<<"\n";} > #include<stdio.h>Nint main(){int i=0,j;for(;i<4;++i,puts(""))for(j=0;j<16;)putchar('0'+j++/(1<<i)%2);} #include<stdio.h>Nint main(){int i=4,j;for(;i--;puts(""))for(j=16;j--;putchar('1'-(j>>3-i)%2));} #include<stdio.h>Nint main(){printf("%016b\n%016b\n%016b\n%016b\n",21845,13107,3855,255);} But %b is AFAIK not part of the standard. Marcel |
asetofsymbols@gmail.com: Apr 10 11:32AM -0700 int i,r;main(k){for(;k<16;r%16?0:(puts(""),k=i))for(i=0;i<2*k;++i,++r)putchar('1'-(i<k));} |
Victor Bazarov <v.bazarov@comcast.invalid>: Apr 10 09:16AM -0400 On 4/9/2015 6:44 PM, Doug Mika wrote: > duckBilledP.Mammal::Animal::Age=25; > //duckBilledP.Animal::Age=25; //why wouldn't this work? > } Actually, given the hierarchy the simple duckBilledP.Age = 25; ought to do. However, if somewhere in the derived classes there were a member 'Age', the scope resolution would help avoiding ambiguity, IIRC. V -- I do not respond to top-posted replies, please don't ask |
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