Hello,
I am currently writing a gemetric multigrid solver as an exercise at univeristy. Until now i have developed the solver with gcc. But I want to port this project to Visual C++ 2005 Express. My Problem is that exacty the same code compiled with gcc give me the right results. But if i compile it with Visual C++ the program runs but do not give me the right results. The solving process is iterative so the defect is getting smaler with every iteration.
Here is a comparision between VC and gcc:
Visual Studio 2005 Express: gcc:
Iteration defect defect
1 28304.8 28304.8
2 1127.11 1127.11
3 66.9525 66.9567
4 4.17654 4.17567
5 0.272856 0.272841
6 0.0506974 0.0185196
7 204.731 0.00129729
As there only is a diffrenc when the defect gets small i guess that it is a problem with the floating point accuray. But i can't find anything about it. The Program manly uses valarray.
I can't head down the problem to a short code part so i think it is rather sensless to post anything here.
Best regards
Jiri

Numeric Problem
Daniel Schlößer
I am using double and i also tried long double. But in VC sizeof(double) == sizeof(double) = 8, also in gcc is sizeof(double) = 8. With gcc i do not generate any processor specific code and i do not use any special option to increase precission. For the VC compiler i have tested:
/fp:precise /fp:fast /fp:fast (the manual says that the Option /Op has been replaced by /fp)
and all give me wrong results.
Thanks
Jiri
SOYGAMA
No! There is no standard constructor for a double. Or better, they have one, but they do nothing. You can see this when you define a double on the stack.
double Foo()
{
double stackGarbage;
return stakGarbage;
}
As expected there the "default constructor" called, but it does nothing. None of the build in types like int/double have one that does anything! So if you use a double in a vector std::vector<double> and resizing it it will produce garbage values.
The effect you saw might be caused by an implementation detail of the STL used by gcc. They might clear the allocated memory to 0 after allocating the bock for the array. But this is a speed impact, usually there is no need to do that, because later on the default constructor is called. But in the case of int/double and so on, they do nothing. Also this is not required by the standard!
AnAgile
Hi, Martin. I think vector<int>'s constructor will initialize all its element to 0, because it use int() explicitly. Here is the code quoted from STL shipped with VC2005
explicit vector(size_type _Count)
: _Mybase()
{ // construct from _Count * _Ty()
_Construct_n(_Count, _Ty());
}
_Ty() will cause the initialization of int(), which is 0 here. And whats more, STL in VC will not optimize such situations for POD (gcc will use template specialization to optimize these initialization of char by using memset directly)
In most circumstances, these initialization is unnecessary. That's the main reason that I use scoped_array in boost instead of the more advanced vector ^_^
Marioh
KN1123
I am still a little bit confused about this and I read different things about this behaviour!
The default constructor for all basic types is called and it does nothing. This default constructor is called by the allocation of the array!
Correct is that the data is not initialized. But there is a differnece between construction and initialization!
mephista
BillyDvd
And for valarray, the construction process is quite different
explicit valarray(size_t _Count = 0)
{ // construct with _Count * _Ty()
_Tidy();
_Myres = _Count;
_Grow(_Count);
}
_Grow has following prototype:
void _Grow(size_t _Count, const _Ty *_Ptr = 0, ize_t _Inc = 0);
it use _Ty * here, so no initialization will occur by default (even for class like complex) . I'm quite curious about these design difference. Are they mainly due to effective consideration And in my opion, this behavior is quite incompatible with the description in the comment "// construct with _Count * _Ty()"
amc
Different! Not wrong! :-)
The problem is that floating point math is always something dependent on the way it is done!
vien11
I found the problem. I am initilizing valarrays with
std::valarray<double> u(Nx*Ny);
The c++ standart says that u is initilized with the default constructor of T. For double that should be 0.0, so I used u as it were initilized with 0.0. For gcc this was right, but in VC 8 i have to write:
std::valarray<double> u(0.0,Nx*Ny);
Do i understand the c++ Standart wrong or is this none standart behaviour
Best regards
Jiri
oclaros
Hi, Martin.
After reading the standard, I think this is the bug of the valarray template:
26.3.2.1 valarray constructors
explicit valarray ( size_t );
2 The array created by this constructor has a length equal to the value of the argument. The elements of the array are constructed using the default constructor for the instantiating type T .
So, the behavior of left the elements uninitialized is not compatible with the standard though it is more efficient when the array is large.
AggieNut
Best regards
Jiri
Congi
Did you use float or double Did you use any flags to increase precission in the gcc compiler Sure that both compiler are using the same size for its float/double values.
The VC compiler has the option /Op to improve floating point consistency.