|
|||
|
I have a problem about an object ( B const * array[ ] ) in global.
Please see source program below. I provide B * const array [ ] in global scope in my first try, but their lifetime seems to be already end when the program goes to the enrty of main function. why is it so ? I usually provide char const * array[ ] in global and goes well. In which page does the standard describe about lifetime in this case ? Maybe '3.8 Object lifetime", but which phrases are applied in this case? In my second try, it goes well but another structure (class) is required. Is there any better way to provide B * pointer to handle late binding ? Thank you. Tsunehiko ------------------------------------------------------------------ #include <string> #include <iostream> using std::string; using std::cout; class B { public: B( string str ) : str_m( str ) { } string get_str( void ) const { return str_m; } virtual int fnc( void ) const = 0; virtual ~B( ) { } private: std::string str_m; }; class D : public B { public: D( string str ) : B( str ) { } virtual int fnc( void ) const { return 1; } }; struct Create_B { string str_m; B * (*fnc)( string str ); }; B * create_D( string str ) { return new D( str ); } B const * list_0[ ] = { & D( "D0" ), }; D const list_1[ ] = { D( "D1" ), }; Create_B list_2[ ] = { { "D2", &create_D }, }; int main( void ) { // My first try, but fails s = list_0[ 0 ]->get_str( ); cout << s << "\n"; // just for checking what is wrong with the first try string s; s = list_1[ 0 ].get_str( ); cout << s << "\n"; // My second try runs without error, // but another class 'Create_B' is required B * p = list_2[ 0 ].fnc( list_2[ 0 ].str_m ); s = p->get_str( ); cout << s << "\n"; return 0; } |
|
|
||||
|
||||
|
|
|
|||
|
soft wind wrote:
> [..] > B const * list_0[ ] = { > & D( "D0" ), > }; Here you initilialise the pointer (the first element of your array) with the address of a *temporary*. The temporary does exist at the time when you take its address (and since it's an object of class type, you're allowed to take its address), but it is destroyed at the end of this statement, so the address that *was* valid during initialisation is not valid in any other point in your program. > [..] V -- Please remove capital 'A's when replying by e-mail I do not respond to top-posted replies, please don't ask |
|
|||
|
Victor Bazarov <v.Abaza...@comAcast.net> wrote:
> but it is destroyed at the end of this > statement, so the address that *was* valid during initialisation is not > valid in any other point in your program. Thank you. Your statement is reasonable to me, but is it the same with this case ? char const * array[ ] = { "123", "ABC", }; What is different between this case and my first try ? Tsunehiko |
|
|||
|
soft wind wrote:
> Victor Bazarov <v.Abaza...@comAcast.net> wrote: > >> but it is destroyed at the end of this >> statement, so the address that *was* valid during initialisation is not >> valid in any other point in your program. > > Thank you. > > Your statement is reasonable to me, > but is it the same with this case ? No. > > char const * array[ ] = { > "123", > "ABC", > }; > > What is different between this case and my first try ? The biggest difference is that here there are no *temporaries*. The string literals exist from before the program starts and until the program finishes, and the address of the first element of each of those arrays (yes, each literal is itself an array) stays valid while your program is running. V -- Please remove capital 'A's when replying by e-mail I do not respond to top-posted replies, please don't ask |
|
|||
|
On Feb 8, 1:55 pm, soft wind <soft_w...@nifty.com> wrote:
> I have a problem about an object ( B const * array[ ] ) in > global. Please see source program below. > I provide B * const array [ ] in global scope in my first try, > but their lifetime seems to be already end when the program > goes to the enrty of main function. > why is it so ? > I usually provide char const * array[ ] in global and goes > well. In which page does the standard describe about > lifetime in this case ? > Maybe '3.8 Object lifetime", but which phrases are applied in this > case? > In my second try, it goes well but another structure (class) > is required. Is there any better way to provide B * pointer > to handle late binding ? > ------------------------------------------------------------------ > #include <string> > #include <iostream> > using std::string; > using std::cout; > class B { > public: > B( string str ) : str_m( str ) { } > string get_str( void ) const { return str_m; } > virtual int fnc( void ) const = 0; > virtual ~B( ) { } > private: > std::string str_m; > }; > class D : public B { > public: > D( string str ) : B( str ) { } > virtual int fnc( void ) const { return 1; } > }; > struct Create_B { > string str_m; > B * (*fnc)( string str ); > }; > B * create_D( string str ) > { > return new D( str ); > } > B const * list_0[ ] = { > & D( "D0" ), This shouldn't compile. I don't see any user defined overload of D: perator&, so & is the built in operator, which requiresan lvalue. If it does compile, you're using an implementation specific extention, not C++, and you'll have to verify in the implementation documentation what it means with regards to lifetime of objects. (Personally, I'd be very suspicious of a compiler with such extensions, as it suggests that the people who wrote the compiler don't understand C++.) > }; > D const list_1[ ] = { > D( "D1" ), > }; > Create_B list_2[ ] = { > { "D2", &create_D }, > }; > int main( void ) Just a nit, but the void marks you as a C programmer, and gives the impression that you don't know C++. > { > // My first try, but fails > s = list_0[ 0 ]->get_str( ); What is "s"? I don't see it declared anywhere. As for the rest, see your compiler documentation; the initialization of list_0 isn't C++, but some compiler specific extention, so only the compiler documentation can tell you what to expect. > cout << s << "\n"; > // just for checking what is wrong with the first try > string s; > s = list_1[ 0 ].get_str( ); > cout << s << "\n"; This is well defined behavior: it should call the get_str function on a copy of the D object used to initialize list_1. > // My second try runs without error, > // but another class 'Create_B' is required > B * p = list_2[ 0 ].fnc( list_2[ 0 ].str_m ); > s = p->get_str( ); > cout << s << "\n"; This is also legal, but has distinctly different semantics than the first two, since it creates a new object on the heap. > return 0; > } -- James Kanze |
|
|||
|
On Feb 8, 2:46 pm, Victor Bazarov <v.Abaza...@comAcast.net> wrote:
> soft wind wrote: > > [..] > > B const * list_0[ ] = { > > & D( "D0" ), > > }; > Here you initilialise the pointer (the first element of your > array) with the address of a *temporary*. Maybe. The code is not legal C++, and requires diagnostic. If he doesn't get an error message, he's not using a C++ compiler, but something else. And what the statement does depends on what that something else defines it to do. -- James Kanze |
|
|||
|
Victor Bazarov <v.Abaza...@comAcast.net> wrote:
> > char const * array[ ] = { > > * * "123", > > * * "ABC", > > }; > > > What is different between this case and my first try ? > > The biggest difference is that here there are no *temporaries*. *The > string literals exist from before the program starts and until the > program finishes, I am wondering what makes difference in general. I mean, In what cases is a temporary created when listed in an array in global scope ? Class (struct) or not ? How about in this case. D const list_1[ ] = { D( "D1" ), }; Class object is listed in an array but seems to stay all the time. Tsunehiko |
|
|||
|
Victor Bazarov <v.Abaza...@comAcast.net> wrote:
> > char const * array[ ] = { > > * * "123", > > * * "ABC", > > }; > > > What is different between this case and my first try ? > > The biggest difference is that here there are no *temporaries*. *The > string literals exist from before the program starts and until the > program finishes, I am wondering what makes difference in general. I mean, In what cases is a temporary created when listed in an array in global scope ? Class (struct) or not ? How about in this case. D const list_1[ ] = { D( "D1" ), }; Class object is listed in an array but seems to stay all the time. Tsunehiko |
|
|||
|
soft wind wrote:
> Victor Bazarov <v.Abaza...@comAcast.net> wrote: >>> char const * array[ ] = { "123", "ABC", }; What is different >>> between this case and my first try ? >> The biggest difference is that here there are no *temporaries*. >> The string literals exist from before the program starts and until >> the program finishes, > > I am wondering what makes difference in general. I mean, In what > cases is a temporary created when listed in an array in global scope > ? Class (struct) or not ? Any time you use the <typename> ( params(opt) ) *expression*, it creates a temporary. In your case <typename> == D, params == "D1". That expression is sometimes called "function-style cast". Even when you do 'int(31.15)', it creates a temporary of type 'int', which only lives until the full expression is evaluated or until the object is fully initialised (if used in the initialisation expression). The difference (unfortunate) for you is that you're allowed to take the address of a class temporary, but not of a temporary of a built-in type. > How about in this case. > > D const list_1[ ] = { D( "D1" ), }; > > Class object is listed in an array but seems to stay all the time. Here you initialise *an object* with another object, which is copy-initialisation and is performed by the class' copy c-tor. While there is a temporary created, no address is taken and retained (to become invalid). That is, of course, if your copy c-tor does not do anything funny. V -- Please remove capital 'A's when replying by e-mail I do not respond to top-posted replies, please don't ask |
|
|||
|
James Kanze <james.ka...@gmail.com> wrote:
> This shouldn't compile. *I don't see any user defined overload > of D: perator&, so & is the built in operator, which requires> an lvalue. I understand your explanation but where can I find in the Standard why this shouldn't compile ? gcc version 4.0.1 and around 4.4 gave warning but created exe. Visual C++ 2008 Express gave no warning and error at the highest warning level. > > * * // My first try, but fails > > * * s = list_0[ 0 ]->get_str( ); > > What is "s"? *I don't see it declared anywhere. Sorry, I exchanged the position of the code fragment just before posting. Tsunehiko |
|
|||
|
On 9 Feb, 13:12, Victor Bazarov <v.Abaza...@comAcast.net> wrote:
> soft wind wrote: [...] > That expression is sometimes called "function-style cast". > Even when you do 'int(31.15)', it creates a temporary of type > 'int', which only lives until the full expression is evaluated > or until the object is fully initialised (if used in the > initialisation expression). The difference (unfortunate) for > you is that you're allowed to take the address of a class > temporary, but not of a temporary of a built-in type. Only if the class overloads the address-of operator. -- James Kanze |
|
|||
|
On 9 Feb, 13:25, soft wind <soft_w...@nifty.com> wrote:
> James Kanze <james.ka...@gmail.com> wrote: > > This shouldn't compile. I don't see any user defined > > overload of D: perator&, so & is the built in operator,> > which requires an lvalue. > I understand your explanation but where can I find in the > Standard why this shouldn't compile ? §5.3.1/2: The result of the unary & operator is a pointer to its operand. The operand shall be an lvalue or a qualifiedid. In the first case, if the type of the expression is "T," the type of the result is "pointer to T." In particular, the address of an object of type "cv T" is "pointer to cv T," with the same cv-qualifiers. For a qualified-id, if the member is a static member of type "T", the type of the result is plain "pointer to T." If the member is a nonstatic member of class C of type T, the type of the result is "pointer to member of class C of type T." > gcc version 4.0.1 and around 4.4 gave warning but created exe. A warning is a diagnostic. And are you sure you invoked g++ as a C++ compiler: "g++ -std=c++98", or something along those lines? > Visual C++ 2008 Express gave no warning and error at the > highest warning level. VC++ does have a number of extensions. Still, this one surprises me---the C++ rule is just an extension of the C rule, and has been that way from the very beginning. -- James Kanze |
|
|||
|
soft wind ha scritto:
> James Kanze <james.ka...@gmail.com> wrote: >> This shouldn't compile. I don't see any user defined overload >> of D: perator&, so & is the built in operator, which requires>> an lvalue. > > I understand your explanation but where can I find in the Standard > why this shouldn't compile ? > > gcc version 4.0.1 and around 4.4 gave warning but created exe. > Visual C++ 2008 Express gave no warning and error at the > highest warning level. That's because you must tell VC not to use Microsoft's language extensions by specifying /Za. With /Za specified, you'll get the following errors: vc.cpp(37) : error C2102: '&' requires l-value vc.cpp(37) : error C2466: cannot allocate an array of constant size 0 x-post & f'up to microsoft.public.vc.language -- Christian Hackl hacki@sbox.tugraz.at Milano 2008/2009 -- L'Italia chiamò, sì! |
|
|||
|
Victor Bazarov <v.Abaza...@comAcast.net> wrote:
> > > D const list_1[ ] = { D( "D1" ), }; > > > Class object is listed in an array but seems to stay all the time. > > Here you initialise *an object* with another object, which is > copy-initialisation and is performed by the class' copy c-tor. Thank you. My confusion clears up. In this case, two step operation. A temporary is created by ctor, then copied to initialize global object by cpoy ctor. Tsunehiko |
|
|||
|
James Kanze <james.ka...@gmail.com> wrote:
> > I understand your explanation but where can I find in the > > Standard why this shouldn't compile ? > > §5.3.1/2: Thank you. > A warning is a diagnostic. *And are you sure you invoked g++ as > a C++ compiler: "g++ -std=c++98", or something along those > lines? I invoked g++ : gxx -pedantic -Wall test1.cpp When file extension is *.cpp, gcc is invoked as a C++ compiler as a default. Right ? Tsunehiko |
|
|
|
|
![]() |
| Popular Tags in the Forum |
| array, const, gobal |
| Thread Tools | |
| Display Modes | |
|
|
Similar Threads
|
||||
| Thread | Thread Starter | Forum | Replies | Last Post |
| Program for license: million dollars [std::ostream& | http://alexslemonade.org | Newsgroup comp.lang.lisp | 8 | 10-19-2009 06:19 PM |
| Program for license: million dollars [std::ostream& | http://alexslemonade.org | Newsgroup comp.lang.fortran | 7 | 10-17-2009 07:54 AM |
| Overloaded function lookup with const/volatile | Marcel Müller | Newsgroup comp.language.c++ | 8 | 08-20-2009 10:02 AM |
| similar Perl data structure? | ela | Newsgroup comp.lang.c | 61 | 04-22-2009 10:32 PM |
| Copying Few Octets from Vector | smilesonisamal@gmail.com | Newsgroup comp.language.c++ | 18 | 04-13-2009 04:58 PM |