Thread overview | |||||||||
---|---|---|---|---|---|---|---|---|---|
|
November 19, 2003 DMC 8.38n Bug - Static & Template | ||||
---|---|---|---|---|
| ||||
There appears to be a bug with DMC in its use of static variables. This code compiles and works fine with VC6,GCC3.2,and IntelC 7.1: #include <stdio.h> #include <vector> #define VECTOR std::vector template <typename T> class A { public: void PrintX() { printf("x size:%d\n",vector().size()); } static std::vector<T>& vector() { static std::vector<T> instance; return instance; } }; template <typename T> class B { public: void SetA(T &t) { A<T>::vector().push_back(t); printf("B::SetA, x size:%d\n",A<T>::vector().size()); } }; class C : public B<int> { public: C() { printf("C\n"); int val=77; SetA(val); } }; C global_variable_c; int main() { C c; A<int> a; a.PrintX(); } The output produced by all other compilers is: C B::SetA, x size:1 C B::SetA, x size:2 x size:2 But for DMC the output is: C B::SetA, x size:1 C B::SetA, x size:1 x size:1 Thanks. If anyone can tell me a work-around that would also be usefull. PS:Im not sure where the bug reports are supposed to go. Here? |
November 19, 2003 Re: DMC 8.38n Bug - Static & Template | ||||
---|---|---|---|---|
| ||||
Posted in reply to Adrian Boeing | Yes, this is the right place to report bugs. I'll check it out. -Walter |
December 28, 2003 Re: DMC 8.38n Bug - Static & Template | ||||
---|---|---|---|---|
| ||||
Posted in reply to Walter | In article <bpfj9g$2qna$1@digitaldaemon.com>, Walter says... > >Yes, this is the right place to report bugs. I'll check it out. -Walter > > Hi, I'm just wondering if you've gotten around to looking at this yet? Can anyone suggest a work-around so that the program will run correctly? Is there some method to order the initialization of static variables? (something like #pragma init_seg for MSVC?) Thanks. Here is the example code again: #include <stdio.h> #include <vector> #define VECTOR std::vector template <typename T> class A { public: void PrintX() { printf("x size:%d\n",vector().size()); } static std::vector<T>& vector() { static std::vector<T> instance; return instance; } }; template <typename T> class B { public: void SetA(T &t) { A<T>::vector().push_back(t); printf("B::SetA, x size:%d\n",A<T>::vector().size()); } }; class C : public B<int> { public: C() { printf("C\n"); int val=77; SetA(val); } }; C global_variable_c; int main() { C c; A<int> a; a.PrintX(); } And the correct(ie: what I want) program output: C B::SetA, x size:1 C B::SetA, x size:2 x size:2 But for DMC the output is: C B::SetA, x size:1 C B::SetA, x size:1 x size:1 Thank You! |
December 29, 2003 Re: DMC 8.38n Bug - Static & Template | ||||
---|---|---|---|---|
| ||||
Posted in reply to Adrian Boeing | >Hi, I'm just wondering if you've gotten around to looking at this yet?
>
>Can anyone suggest a work-around so that the program will run correctly?
Writing it clearly might be a start. Why call a function "PrintX()" when it is
printing the size of an array? Wouldn't it make more sense to call it
"PrintArraySize()"?
One of the most basic principles of good coding is that of separating commands from queries. Queries return a value but are class const. Commands are non-const and return void. And you never write a function that causes side-effects that aren't obvious from the functon name. If you *need* to print from a constructor, such as to have a log of when it executes, it should print something like "class C's default ctor executing", not just "C".
As it is, your code is so inscrutable I find it impossible to help you, as I get lost trying to understand it.
And no, there is no way to determine the order of static initialization. And
there will never be; otherwise we'd have to have a language within the language.
What you can do is replace static variables with functions, so that if static
int A is defined in terms of static int B, then static int A(){...} can simply
call static int B(){...} during its initialization. If B is a constant
primitive, like 77, just write it like static int B(){ return 77; } for
consistency; and everything will work out; it's called lazy initialization.
But it might be a problem when using such "constants" where a compile time
constant is needed, such as in sizing an array. Templates might be better in
such case, some basic metaprogramming. But in most cases, compile time constants
are not needed if the design is done right: Use vector, instead of array, etc.
HTH
|
January 05, 2004 Re: DMC 8.38n Bug - Static & Template | ||||
---|---|---|---|---|
| ||||
Posted in reply to dan | Hi, Thanks for the reply. (updated code at end) >Writing it clearly might be a start. Why call a function "PrintX()" when it is >printing the size of an array? Wouldn't it make more sense to call it >"PrintArraySize()"? Sure, added some clearer code with comments. This code is not the actual code I am trying to use, it is just a simplified version which illustrates the problem. This is why the code appears to do "nothing" >And no, there is no way to determine the order of static initialization. And there will never be; otherwise we'd have to have a language within the language. Shame. That could have solved this problem. >What you can do is replace static variables with functions, so that if static int A is defined in terms of static int B, then static int A(){...} can simply call static int B(){...} during its initialization. This is what I have tried to do, which is why class A's returnvectorinstance simply returns an instance of a static vector. The desired output: class C's default ctor executing class B::AddToVector::Vector size:1 class C's default ctor executing class B::AddToVector::Vector size:2 Vector size:2 DMC's output: class C's default ctor executing class B::AddToVector::Vector size:1 class C's default ctor executing class B::AddToVector::Vector size:1 Vector size:1 Sorry for any confusion caused. Here is the code again: #include <stdio.h> #include <stdlib.h> #include <vector> template <typename T> class A { public: //this displays the number of items in the array static void PrintArraySize() { printf("Vector size:%d\n",returnvectorinstance().size()); } //this should ensure that the vector exists. static std::vector<T>& returnvectorinstance() { static std::vector<T> instance; return instance; } }; template <typename T> class B { public: //this adds an entry to the static vector, in class A void AddToVector(T &t) { A<T>::returnvectorinstance().push_back(t); printf("class B::AddToVector::"); A<T>::PrintArraySize(); } }; class C : public B<int> { public: //C's default ctor adds a value to A's static vector C() { printf("class C's default ctor executing\n"); int val=rand(); AddToVector(val); } }; C global_variable_c; //this variable should add an entry to A's static vector (ie: 1 entry) int main() { C c; //this variable should increment the number of entrys in A's static vector (ie: 2 entries) A<int> a; a.PrintArraySize(); //with VC,gcc,and icc a.PrintArraySize, will print "2". //however, with DMC it will print "1". } |
January 05, 2004 Re: DMC 8.38n Bug - Static & Template | ||||
---|---|---|---|---|
| ||||
Posted in reply to Adrian Boeing | Well quickly glancing over the code provided, I would say you're right, it should return 2.
Have you tried to make 'returnvectorinstance()' _not_ a class member?
e.g:
template < class T > static vector < T > &returnvectorinstance ()
{
static vector<T> instance;
return instance;
}
This should work even with 8.38 (I'm using the same contruct and never had troubles)
Arjan Knepper
Adrian Boeing wrote:
> Hi, Thanks for the reply. (updated code at end)
>
>
>>Writing it clearly might be a start. Why call a function "PrintX()" when it is
>>printing the size of an array? Wouldn't it make more sense to call it
>>"PrintArraySize()"?
>
>
> Sure, added some clearer code with comments. This code is not the actual code I
> am trying to use, it is just a simplified version which illustrates the problem.
> This is why the code appears to do "nothing"
>
>
>>And no, there is no way to determine the order of static initialization. And
>>there will never be; otherwise we'd have to have a language within the language.
>
>
> Shame. That could have solved this problem.
>
>
>>What you can do is replace static variables with functions, so that if static
>>int A is defined in terms of static int B, then static int A(){...} can simply
>>call static int B(){...} during its initialization.
>
>
> This is what I have tried to do, which is why class A's returnvectorinstance
> simply returns an instance of a static vector.
>
> The desired output:
>
> class C's default ctor executing
> class B::AddToVector::Vector size:1
> class C's default ctor executing
> class B::AddToVector::Vector size:2
> Vector size:2
>
> DMC's output:
> class C's default ctor executing
> class B::AddToVector::Vector size:1
> class C's default ctor executing
> class B::AddToVector::Vector size:1
> Vector size:1
>
> Sorry for any confusion caused.
>
> Here is the code again:
>
> #include <stdio.h>
> #include <stdlib.h>
> #include <vector>
>
> template <typename T>
> class A {
> public:
> //this displays the number of items in the array
> static void PrintArraySize() {
> printf("Vector size:%d\n",returnvectorinstance().size());
> }
> //this should ensure that the vector exists.
> static std::vector<T>& returnvectorinstance()
> {
> static std::vector<T> instance;
> return instance;
> }
> };
>
> template <typename T>
> class B {
> public: //this adds an entry to the static vector, in class A
> void AddToVector(T &t) {
> A<T>::returnvectorinstance().push_back(t);
> printf("class B::AddToVector::");
> A<T>::PrintArraySize();
> }
> };
>
> class C : public B<int> {
> public:
> //C's default ctor adds a value to A's static vector
> C() {
> printf("class C's default ctor executing\n");
> int val=rand();
> AddToVector(val);
> }
> };
>
> C global_variable_c; //this variable should add an entry to A's static vector
> (ie: 1 entry)
>
> int main() {
> C c; //this variable should increment the number of entrys in A's static vector
> (ie: 2 entries)
>
> A<int> a;
> a.PrintArraySize(); //with VC,gcc,and icc a.PrintArraySize, will print "2".
> //however, with DMC it will print "1".
> }
>
>
|
January 07, 2004 Re: DMC 8.38n Bug - Static & Template | ||||
---|---|---|---|---|
| ||||
Posted in reply to Arjan Knepper | Hi Arjan, Thank you, the example you provided works fine. Hopefully the bug will be fixed anyway. Cheers, -Adrian In article <btc4id$u3$1@digitaldaemon.com>, Arjan Knepper says... > >Well quickly glancing over the code provided, I would say you're right, it should return 2. > >Have you tried to make 'returnvectorinstance()' _not_ a class member? >e.g: > >template < class T > static vector < T > &returnvectorinstance () >{ > static vector<T> instance; > > return instance; >} > >This should work even with 8.38 (I'm using the same contruct and never had troubles) > >Arjan Knepper |
Copyright © 1999-2021 by the D Language Foundation