0

[Christian Hacki and Barry point out that a question has been asked specifically about complex previously. My question is more general, as it applies to std::vector, std::array, and all the container classes that use allocators. Also, the answers on the other question are not adequate, IMO. Perhaps I could bump the other question somehow.]

I have a C++ application that uses lots of arrays and vectors of real values (doubles) and complex values. I do not want them initialized to zeros. Hey compiler and STL! - just allocate the dang memory and be done with it. It's on me to put the right values in there. Should I fail to do so, I want the program to crash during testing.

I managed to prevent std::vector from initializing with zeros by defining a custom allocator for use with POD's. (Is there a better way?)

What to do about std::complex? It is not defined as a POD. It has a default constructor that spews zeros. So if I write

std::complex<double> A[compile_time_const];

it spews. Ditto for

std::array <std::complex<double>, compile_time_constant>;

What's the best way to utilize the std::complex<> functionality without provoking swarms of zeros?

[Edit] Consider this actual example from a real-valued FFT routine.

{
            cvec Out(N);
            for (int k : range(0, N / 2)) {
                complex Evenk = Even[k];
                complex T = twiddle(k, N, sgn);
                complex Oddk = Odd[k] * T;
                Out[k] = Evenk + Oddk;
                Out[k + N / 2] = Evenk - Oddk; // Note. Not in order
            }
            return Out;
        }
Jive Dadson
  • 16,680
  • 9
  • 52
  • 65
  • How about: `struct number { double value; number() {} };` – Sam Varshavchik Dec 03 '16 at 15:55
  • @juanchopanza I think POD means a class without constructors, destructors or virtual member functions. Please elucidate. – Jive Dadson Dec 03 '16 at 16:00
  • Why do you want it to crash only during testing? And what's so bad about those initialisations? Have you measured an actual performance penalty? – Christian Hackl Dec 03 '16 at 16:06
  • @ChristianHackl Those intialisations may occur frequently (for every new `vector`) but cannot be done in parallel. So they are bad. fullstop. – Walter Dec 03 '16 at 16:07
  • @Walter: If you want to deal with raw memory, then don't use `std::vector`, it's as easy as that. The way you have phrased your question and comment, however, make me think that you have **not** measured performance and are guessing about potential bottlenecks. – Christian Hackl Dec 03 '16 at 16:10
  • Come to think of it, the real answer to the question would be: Don't initialise the elements before you know their correct values. – Christian Hackl Dec 03 '16 at 16:12
  • @ChristianHackl Which questions are you talking about (this here is not mine)? It would be easy for the implementations to add a boolean template parameter which defaults to `true` and indicates whether default initialisation of built-in types is performed or not. Then the user must deliberately switch that off if she wants to. – Walter Dec 03 '16 at 16:21
  • @Christian Hacki - That's not possible with plain old C-type arrays. Or how about the actual example I just added? – Jive Dadson Dec 03 '16 at 16:23
  • @Walter: Yes, I realised just now that you are not the OP. You certainly sounded like him, as if you knew all the background information about his problem. – Christian Hackl Dec 03 '16 at 16:23
  • Please don't close me out. That other question and its answers leave much to be desired. Me so sad. – Jive Dadson Dec 03 '16 at 16:24
  • @JiveDadson: I don't get it. Why is it not possible? About your example, what exactly is `cvec`? A `std::vector>`? You could just call `reserve(N)` on it and then `push_back` elements inside of the loop. That should be good enough, and it's only a single memory allocation. – Christian Hackl Dec 03 '16 at 16:27
  • @Christian Hacki - Look at the last line of the loop in the example. It is not a "push_back". It's a sort of "push_middle". What is cvec? Well that is the question I am asking, or was until the question go closed. Originally I had cvec defined as std::vector> Would it be out of line for me to ask you to vote to reopen? – Jive Dadson Dec 03 '16 at 16:31
  • I did not say I want the program to crash ONLY during testing when there's a bug. But if there is a bug, I definitely want the program to crash during testing, so it can be fixed. – Jive Dadson Dec 03 '16 at 16:34
  • @Barry My question is NOT an exact duplicate of the previous one. I have the same problem with std::vector. Look. No complex numbers involved.. I "solved" the std::vector problem by writing a custom allocator. Part of my question is whether there is another, better way. Nothing in the "exact duplicate" addresses that. I am bummed that the question got closed. Please reconsider. – Jive Dadson Dec 03 '16 at 16:41
  • @Jive Did you actually read the accepted answer or did you just stop at the title? – Barry Dec 03 '16 at 21:06
  • @Barry. Of course I read it. The accepted answer is insufficient for the example I added above when cvec is defined as std::vector>. That is real code from an FFT package. Furthermore, my question refers to doubles also, when they are put into an std::vector or std::array, etc. I have made considerable progress since I first posted. My application is working just fine now without all those pesky zeros. – Jive Dadson Dec 03 '16 at 21:33
  • @Barry I have thwarted all the gratuitous zeros in the code I am working on. I'm outa here. – Jive Dadson Dec 03 '16 at 21:43
  • @Barry I misspoke above. I should have said it does not work when cvec is defined as std::vector>, where D is defined as in the accepted answer. For one thing, the arithmetic operators are all hidden hidden. Again I am outa here. – Jive Dadson Dec 03 '16 at 21:56

0 Answers0