Topic: new
Author: James Kuyper <kuyper@wizard.net>
Date: 1999/03/05 Raw View
Christopher Eltschka wrote:
...
> Indeed, the only real solution I see is to allocate raw
> memory and then use placement new for each element.
> Probably encapsulated in a nice class.
Like std::uninitialized_fill()?
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: jcoffin@taeus.com (Jerry Coffin)
Date: 1999/03/06 Raw View
In article <36DFE918.6171B413@physik.tu-muenchen.de>,
celtschk@physik.tu-muenchen.de says...
[ I had said: ]
> > A *TempArray = new A[10] = {
> > A(10,3), A(10,3) /* total of ten times */, A(10,3)
> > };
>
> What's that?
An _incredibly_ stupid typo. I'd intended something like:
A *TempArray[10] = { A(10,3), A(10,3) // ...
> I think a compiler will interpret this as a
> declaration, with the initializer being an assignment expression,
> which assigns the expression on the right to the result of
> the new expression.
> This should IMHO be invalid for at least two reasons:
> - new A[10] doesn't give an rvalue
I think you mean it DOES yield an rvalue. If it wasn't an rvalue,
there'd at least be a chance you could assign to it...
> > Note that gcc WILL give a warning (at least as-of egcs 1.1) if you use
> > -Wall with this code. Its default behavior is basically the same as
> > if you used a std::vector, which you should roughly 99% of the time
> > instead of using new directly anyway.
>
> Did you try g++ -ansi -pedantic-errors?
No -- only -ansi -pedantic. I'm personally not very concerned whether
what it yields is called an error or a warning...
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: "John Hickin" <hickin@nortelnetworks.com>
Date: 1999/03/03 Raw View
Garrett Potts wrote:
>#include <iostream>
>
> class A
> {
> public:
> A(int X,int Y) {std::cout << X << " " << Y << std::endl;}
> };
> A *TempArray = new A[10](10,3);
Arrays must be default constructable.
A work-around to your problem could be to use a template:
template<int X, int Y> class AXY : public A
{
AXY() : A(X,Y) { }
};
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: David R Tribble <dtribble@technologist.com>
Date: 1999/03/04 Raw View
Garrett Potts wrote:
>> I was just testing a few things out to convince myself that it
>> couldn't be done and I do not get the same thing on different
>> compilers:
>>
>> #include <iostream>
>>
>> class A
>> {
>> public:
>> A(int X, int Y)
>> { std::cout << X << " " << Y << std::endl; }
>> };
>>
>> int main()
>> {
>> A *TempArray = new A[10](10,3);
>> return 0;
>> }
>>
>> Now in Borland Builder 3.0 and C++ 5.02 This is a compiler error as I
>> expected. I also have installed on my computer gnu win32 port of
>> g++. I have the newest version from cygnus and when it compiles the
>> program above it compiles it the way I would like it to compile. It
>> will call the constructor 10 times for each object. Is this part of
>> the new standard added in this past year? Which is suppose to be
>> correct? I always assumed that the Borland way was the correct
>> response to the above example.
Christopher Eltschka wrote:
> The standard doesn't allow it (can anyone explain why?)
So how does one go about initializing/constructing the elements
of an entire array? Is there a better way than:
int main()
{
A * arr = new A[10]; // Each arr[i] is default init'd
for (int i = 0; i < 10; i++)
new(&arr[i]) A(10, 3); // Call A::A() on each arr[i]
}
The same question applies to explicit member initializers in
constructors for classes with array members:
class B
{
A arr[10];
public:
B();
};
B::B():
arr(10, 3?) // How do we init all arr[i] to A(3, 10)?
{
...
}
-- David R. Tribble, dtribble@technologist.com --
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: James Kuyper <kuyper@wizard.net>
Date: 1999/03/04 Raw View
David R Tribble wrote:
....
> So how does one go about initializing/constructing the elements
> of an entire array? Is there a better way than:
>
> int main()
> {
> A * arr = new A[10]; // Each arr[i] is default init'd
>
> for (int i = 0; i < 10; i++)
> new(&arr[i]) A(10, 3); // Call A::A() on each arr[i]
> }
You can avoid the unnecessary default initialization of the array by
using std::uninitialized_fill<>() or std::uninitialized_fill_n<>():
A *arr = (A*) new unsigned char[10*sizeof(A)];
Note: the standard has wording about 'new' that guarantees that an array
of unsigned char must be suitably aligned for any object small enough to
fit in it.
unititialized_fill_n(arr, 10, A(10,3));
> The same question applies to explicit member initializers in
> constructors for classes with array members:
>
> class B
> {
> A arr[10];
> public:
> B();
> };
>
> B::B():
> arr(10, 3?) // How do we init all arr[i] to A(3, 10)?
> {
> ...
> }
The same techique applies, but simpler since the memory's already been
allocated.
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: jcoffin@taeus.com (Jerry Coffin)
Date: 1999/03/04 Raw View
In article <7bhth8$noc$1@fir.prod.itd.earthlink.net>,
potts@maelstrom.cs.fit.edu says...
> Hello:
>
> I was just testing a few things out to convince myself that it couldn't be
> done and I do not get the same thing on different compilers:
>
> #include <iostream>
>
> class A
> {
> public:
> A(int X,int Y) {std::cout << X << " " << Y << std::endl;}
> };
>
> int main()
> {
> A *TempArray = new A[10](10,3);
>
> return 0;
> }
Borland is right -- this shouldn't be allowed. To initialize an
array, you have to use explicit array style initialization:
A *TempArray = new A[10] = {
A(10,3), A(10,3) /* total of ten times */, A(10,3)
};
Otherwise, your class needs a default ctor to create an array.
Note that gcc WILL give a warning (at least as-of egcs 1.1) if you use
-Wall with this code. Its default behavior is basically the same as
if you used a std::vector, which you should roughly 99% of the time
instead of using new directly anyway.
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: James Kuyper <kuyper@wizard.net>
Date: 1999/03/04 Raw View
John Hickin wrote:
>
> Garrett Potts wrote:
> >#include <iostream>
> >
> > class A
> > {
> > public:
> > A(int X,int Y) {std::cout << X << " " << Y << std::endl;}
> > };
>
> > A *TempArray = new A[10](10,3);
>
> Arrays must be default constructable.
>
> A work-around to your problem could be to use a template:
>
> template<int X, int Y> class AXY : public A
> {
> AXY() : A(X,Y) { }
> };
Wouldn't it be much simpler to simply declare a default constructor?
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: Christopher Eltschka <celtschk@physik.tu-muenchen.de>
Date: 1999/03/05 Raw View
Jerry Coffin wrote:
>
> In article <7bhth8$noc$1@fir.prod.itd.earthlink.net>,
> potts@maelstrom.cs.fit.edu says...
> > Hello:
> >
> > I was just testing a few things out to convince myself that it couldn't be
> > done and I do not get the same thing on different compilers:
> >
> > #include <iostream>
> >
> > class A
> > {
> > public:
> > A(int X,int Y) {std::cout << X << " " << Y << std::endl;}
> > };
> >
> > int main()
> > {
> > A *TempArray = new A[10](10,3);
> >
> > return 0;
> > }
>
> Borland is right -- this shouldn't be allowed. To initialize an
> array, you have to use explicit array style initialization:
>
> A *TempArray = new A[10] = {
> A(10,3), A(10,3) /* total of ten times */, A(10,3)
> };
What's that? I think a compiler will interpret this as a
declaration, with the initializer being an assignment expression,
which assigns the expression on the right to the result of
the new expression.
This should IMHO be invalid for at least two reasons:
- new A[10] doesn't give an rvalue
- { ... } isn't an expression
However, even if legal, this would be a memory leak.
>
> Otherwise, your class needs a default ctor to create an array.
>
> Note that gcc WILL give a warning (at least as-of egcs 1.1) if you use
> -Wall with this code. Its default behavior is basically the same as
> if you used a std::vector, which you should roughly 99% of the time
> instead of using new directly anyway.
Did you try g++ -ansi -pedantic-errors?
With egcs-1.0.3, this results in:
arrini.cc:20: ANSI C++ forbids initialization of new expression with `='
arrini.cc:20: initialization in array new
Which shows that g++ has obviously another extension here.
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: Christopher Eltschka <celtschk@physik.tu-muenchen.de>
Date: 1999/03/05 Raw View
James Kuyper wrote:
>
> John Hickin wrote:
> >
> > Garrett Potts wrote:
> > >#include <iostream>
> > >
> > > class A
> > > {
> > > public:
> > > A(int X,int Y) {std::cout << X << " " << Y << std::endl;}
> > > };
> >
> > > A *TempArray = new A[10](10,3);
> >
> > Arrays must be default constructable.
> >
> > A work-around to your problem could be to use a template:
> >
> > template<int X, int Y> class AXY : public A
> > {
> > AXY() : A(X,Y) { }
> > };
If A doesn't have a virtual destructor (the class shown above
obviously doesn't have one), you'll have a hard time deleting
the array (you _must_ remember what your parameters on new
have been, to select the same template parameters for a cast
at delete, otherwise your code has undefined behaviour).
If A _does_ have a virtual destructor, you are in no way
ensured that sizeof(AXY<x, y>) == sizeof(A), so array
operations may not work at all.
And of course, this will not work
- if at least one parameter is a floating point type
- if at least one parameter is determined at run time
However, those last two problems can be overcome with
pointers to static variables, or with static variable
members in AXY. Of course, this raises other problems
with reentrancy/thread safety.
>
> Wouldn't it be much simpler to simply declare a default constructor?
Depends.
If you have no way to change A (maybe it's from a third party
library), it may not be simple to make a default constructor.
If there _is_ already a default constructor, but it does the
wrong thing for that special case (while doing the right thing
otherwise), you just _cannot_ supply a second default constructor.
If you have two different arrays to be initialized with two
different values, the default constructor won't work for
both arrays anyway.
Unfortunately, the solution above works only with very
severe limitations.
Indeed, the only real solution I see is to allocate raw
memory and then use placement new for each element.
Probably encapsulated in a nice class.
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: "Garrett Potts" <potts@maelstrom.cs.fit.edu>
Date: 1999/03/03 Raw View
Hello:
I was just testing a few things out to convince myself that it couldn't be
done and I do not get the same thing on different compilers:
#include <iostream>
class A
{
public:
A(int X,int Y) {std::cout << X << " " << Y << std::endl;}
};
int main()
{
A *TempArray = new A[10](10,3);
return 0;
}
Now in Borland Builder 3.0 and C++ 5.02 This is a compiler error as I
expected. I also have installed on my computer gnu win32 port of g++. I
have the newest version from cygnus and when it compiles the program above
it compiles it the way I would like it to compile. It will call the
constructor 10 times for each object. Is this part of the new standard
added in this past year. Which is suppose to be correct. I always assumed
that the Borland way was the correct response to the above example.
Take care and thank you for your help
Garrett Potts
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: Christopher Eltschka <celtschk@physik.tu-muenchen.de>
Date: 1999/03/03 Raw View
Garrett Potts wrote:
>
> Hello:
>
> I was just testing a few things out to convince myself that it couldn't be
> done and I do not get the same thing on different compilers:
>
> #include <iostream>
>
> class A
> {
> public:
> A(int X,int Y) {std::cout << X << " " << Y << std::endl;}
> };
>
> int main()
> {
> A *TempArray = new A[10](10,3);
>
> return 0;
> }
>
> Now in Borland Builder 3.0 and C++ 5.02 This is a compiler error as I
> expected. I also have installed on my computer gnu win32 port of g++. I
> have the newest version from cygnus and when it compiles the program above
> it compiles it the way I would like it to compile. It will call the
> constructor 10 times for each object. Is this part of the new standard
> added in this past year. Which is suppose to be correct. I always assumed
> that the Borland way was the correct response to the above example.
>
> Take care and thank you for your help
The standard doesn't allow it (can anyone explain why?)
Try: g++ -ansi -pedantic
or: g++ -ansi -pedantic-errors
Only with those flags, g++ is considered ISO comliant (modulo
bugs and unimplemented features, of course).
g++-2.8.1 and g++ of egcs-1.0.3 both complain about
the code, if given those flags.
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]