Garthy
|
|
« Reply #4840 on: June 05, 2015, 04:56:21 PM » |
|
Re C++ and initialisation:
I'd love to see default initialisation in C++. Ideally I think the default should be zero initialisation with uninitialised variables requiring specific declaration. There are some significant barriers to making this happen though.
I don't think there are any implementation guarantees re uninitialised values, so in terms of backward compatibility, automatically zero-initialising shouldn't pose a major problem with good code in terms of functionality. Having said that, there is no doubt a lot of code out that is buggy and relies on this behaviour. For example: The right value just happens to be in the right place on the stack from a previous call, and it happens to work. Having said that, this seems a really awful reason to dismiss an improvement.
However, there is a lot of code out there that relies on default non-initialisation for performance reasons. For example: The ability to create an uninitialised struct and explicitly fill in the values afterward, possibly selectively. Or creating a fixed size buffer on the stack. Killing the performance of that code is going to (very rightly) annoy a lot of people.
I also have no doubt that there is code out there that relies on the lack of initialisation for entirely legitimate reasons. I can't give any examples, because I don't know any, but I have no doubt it is out there. Breaking this code overnight would be a bad thing.
If such a change was ever seen in C++ it would probably need to be accompanied with a new way to specify explicit non-initialisation, and probably a transitional period of some years.
The issue could be worked around using a new type. If a new type name was chosen, then it'd need to be one that'll work with as much code out there as possible. That either means a lot of existing code will break or the name will be something long or convoluted enough to not collide with existing variable names.
Or it could be solved with templates *twitch* *twitch* *twitch*.
Alternatively, one way to handle it is to define a few types in the "std" namespace that mirror int/float/double, with default zero initialisation. Then you could do something like this:
std::int a; std::int b;
or:
typedef std::int xint; xint a; xint b;
I think this would be one of the better solutions of the limited options available.
Even crazier would be something that would let you override the built-in types with the default-initialising versions on a namespace basis. That'd be cool, concise, and backward compatible.
Something that does help (even if it doesn't solve the issue) is initialisation in class/struct declarations, which has been around since C++11 (and in C since just after the discovery of fire). Unfortunately if you're using Windows you need MSVC2013 or later for it to work.
Anyway, it'd be neat for C++ to get default initialisation by some means.
|
|
|
Logged
|
|
|
|
InfiniteStateMachine
|
|
« Reply #4841 on: June 05, 2015, 06:42:59 PM » |
|
^^ why not the compiler flag I suggested? Is there something I'm overlooking?
At the very least you could do it for primitive types.
|
|
|
Logged
|
|
|
|
Garthy
|
|
« Reply #4842 on: June 05, 2015, 07:33:02 PM » |
|
^^ why not the compiler flag I suggested? Is there something I'm overlooking?
At the very least you could do it for primitive types.
I believe there may be a few obstacles if it was handled in this way: - Inline code in library headers would be compiled in different ways depending on the source module pulling it in. Everything would need to be written (or rewritten) to work correctly. - If a structure is defined with primitive types, objects would be initialised differently depending on the compile flags of the source module that included it. - Using the new feature would require that every build system that might use the code would correctly use the new flag. - You could not control it directly from the source, meaning that you could write code that simply does not work if you provide the wrong options during build, and could not write code that you could even be sure would work correctly if the flag was omitted. You would have to write all code mindful of both of these scenarios- which would mean you'd have to write code against the least common denominator- non-initialisation. And you're back where you started. - I could be mistaken on this, but: I believe the standard does not dictate command-line arguments for compilers at all. This would expand the scope of what the standard covers- which may not be a good thing. - I'm not sure where to start with templates. :{ - New code would face a mountain of existing code that was written without support for default initialisation, reducing its usefulness. Don't get me wrong- I think non-explicit default non-initialisation is outright wrong and no new modern language should have it. However, massive volumes of C++ code are already out there and so backward compatibility is almost certainly going to be a key consideration. I wouldn't underestimate the weight of backward compatibility in an established language- there was strong opposition to the removal of *trigraphs* in C++11, an awful solution to a problem that barely exists any more. Imagine the reaction to a bigger change that could break existing code.
|
|
|
Logged
|
|
|
|
InfiniteStateMachine
|
|
« Reply #4843 on: June 05, 2015, 08:47:47 PM » |
|
Ah, perhaps I should have specified the usage. Basically the flag would be for new projects, not porting existing projects. I think default init is just never going to work for legacy no matter how you roll it.
I realize the standard would be broken but there's already quite a few compilers out there that don't follow the standard. If you look at contract code from the dmars C++ compiler it looks profoundly different (3 function bodies per function).
|
|
|
Logged
|
|
|
|
Garthy
|
|
« Reply #4844 on: June 05, 2015, 09:00:35 PM » |
|
Basically the flag would be for new projects, not porting existing projects.
There are a lot of libraries out there that are useful for new projects- they're the headers you'd probably end up having to worry about. I realize the standard would be broken ...
This could make it difficult to get the support needed to make it into the standard. A commandline option is still an interesting approach though. gcc for example has had a bunch of flags for older, newer, and experimental standards. It had support for much of C++11 before C++11 was even finished, for example. gcc has also had its own language extenstions that you can selectively enable or disable through commandline options. So the approach does have precedent.
|
|
|
Logged
|
|
|
|
oahda
|
|
« Reply #4845 on: June 06, 2015, 01:11:43 AM » |
|
EDIT : Your answer doesn't seem to relate to his question (he she wants zero-initialization, not inferred init). Did you mean to quote a different post?
Nah, I think they got the right person. But the answer doesn't really solve all that much since this is a problem mostly with member variables. I don't really forget to initialise stack variables in the middle of a function or something.
|
|
|
Logged
|
|
|
|
indie11
|
|
« Reply #4846 on: June 07, 2015, 09:46:21 AM » |
|
I am working on a variant of tetris So basically what I want to do is shift blocks downwards Left image is "BEFORE" state Right image is "AFTER" state My solution: I start from down and see if the block is at the BOTTOM or there is another block under it, loop through all the columns and check the same until I reach the end of the list My issue: Is this an optimized solution?
|
|
|
Logged
|
|
|
|
Fallsburg
|
|
« Reply #4847 on: June 07, 2015, 09:57:41 AM » |
|
Probably doesn't matter, in all honesty. Your method is going to be O(n^2), but your n is going to be relatively small I would assume (I would be surprised if it was over 20 per se). A naive n^2 implementation in Python on my computer does it in less than 1/60 of a second for 200, so you're probably fine. A better method would be: newColumn = int[len(oldColumn)]; //initialize newColumn to empty
//assuming 0 is the bottom; int ni = 0 for (int ii = 0; ii < len(oldColumn); ii++){ if (oldColumn[ii] != EMPTY){ newColumn[ni] = oldColumn[ii]; ni++; } }
oldColumn = newColumn;
Of course you should be instantiating a new array every update and should instead have two arrays that you flip and flop between, but you should get the picture.
|
|
|
Logged
|
|
|
|
indie11
|
|
« Reply #4848 on: June 07, 2015, 10:18:49 AM » |
|
Probably doesn't matter, in all honesty. Your method is going to be O(n^2), but your n is going to be relatively small I would assume (I would be surprised if it was over 20 per se). A naive n^2 implementation in Python on my computer does it in less than 1/60 of a second for 200, so you're probably fine. A better method would be: newColumn = int[len(oldColumn)]; //initialize newColumn to empty
//assuming 0 is the bottom; int ni = 0 for (int ii = 0; ii < len(oldColumn); ii++){ if (oldColumn[ii] != EMPTY){ newColumn[ni] = oldColumn[ii]; ni++; } }
oldColumn = newColumn;
Of course you should be instantiating a new array every update and should instead have two arrays that you flip and flop between, but you should get the picture. thanks.. i've already implemented my algorithm and its working fine.. just wondering if there is a solution that takes less than O(n^2) which I guess is not..
|
|
|
Logged
|
|
|
|
Pit
|
|
« Reply #4849 on: June 07, 2015, 10:21:47 AM » |
|
Do you even need 2 arrays? Since ni is always less or equal ii you should be able to do it in one. Just have to set ni and above to "empty" after you're done.
|
|
|
Logged
|
|
|
|
Dacke
|
|
« Reply #4850 on: June 07, 2015, 11:46:05 AM » |
|
Fallsburg's proposed algorithm is O(n), isn't it? You look at every cell once and do a copy if needed.
Pit, yeah, that sounds right.
|
|
|
Logged
|
programming • free software animal liberation • veganism anarcho-communism • intersectionality • feminism
|
|
|
Fallsburg
|
|
« Reply #4851 on: June 09, 2015, 10:29:20 AM » |
|
Yeah, you're right that you can do it in place, wasn't thinking about that.
|
|
|
Logged
|
|
|
|
Sgt. Pepper
Level 1
|
|
« Reply #4852 on: June 09, 2015, 10:54:34 AM » |
|
I had to write an array with 35 elements In Java. Image[] images = { new ImageIcon("res/1.png").getImage(), new ImageIcon("res/2.png").getImage(), new ImageIcon("res/3.png").getImage(), new ImageIcon("res/4.png").getImage(), new ImageIcon("res/5.png").getImage(), new ImageIcon("res/6.png").getImage(), new ImageIcon("res/7.png").getImage(), new ImageIcon("res/8.png").getImage(), new ImageIcon("res/9.png").getImage(), new ImageIcon("res/10.png").getImage(), new ImageIcon("res/11.png").getImage(), new ImageIcon("res/12.png").getImage(), new ImageIcon("res/13.png").getImage(), new ImageIcon("res/14.png").getImage(), new ImageIcon("res/15.png").getImage(), new ImageIcon("res/16.png").getImage(), new ImageIcon("res/17.png").getImage(), new ImageIcon("res/18.png").getImage(), new ImageIcon("res/19.png").getImage(), new ImageIcon("res/20.png").getImage(), new ImageIcon("res/21.png").getImage(), new ImageIcon("res/22.png").getImage(), new ImageIcon("res/23.png").getImage(), new ImageIcon("res/24.png").getImage(), new ImageIcon("res/25.png").getImage(), new ImageIcon("res/26.png").getImage(), new ImageIcon("res/27.png").getImage(), new ImageIcon("res/28.png").getImage(), new ImageIcon("res/29.png").getImage(), new ImageIcon("res/30.png").getImage(), new ImageIcon("res/31.png").getImage(), new ImageIcon("res/32.png").getImage(), new ImageIcon("res/33.png").getImage(), new ImageIcon("res/34.png").getImage(), new ImageIcon("res/35.png").getImage() };
|
|
|
Logged
|
|
|
|
Layl
|
|
« Reply #4853 on: June 09, 2015, 11:16:26 AM » |
|
I had to write an array with 35 elements In Java. <snip> What's wrong with this? Image[] images = new Image[35]; for(int i = 0; i < 35; i++) { images[i] = new ImageIcon("res/" + (i + 1) + ".png").getImage(); }
A bit rusty on my java
|
|
|
Logged
|
|
|
|
Areku
Level 1
Well yeah.
|
|
« Reply #4854 on: June 09, 2015, 11:21:10 AM » |
|
I had to write an array with 35 elements In Java. You know, I think it would have actually been less work to automate the process. def addSprite(self,name,imgfile,framenum=1): imglist = []; for i in range(1,framenum+1): imglist.append("Data/"+imgfile+str(i)+".png"); spr = SpriteMod.Sprite_Anim(name,imglist);
return spr;
is what I'm using for loading sprites atm, with most of the platform-specific tidbits stripped. Iirc it wouldn't be much different using Java? EDIT: Aw dang, ninja'd.
|
|
|
Logged
|
|
|
|
Sgt. Pepper
Level 1
|
|
« Reply #4855 on: June 09, 2015, 11:30:06 AM » |
|
I had to write an array with 35 elements In Java. <snip> What's wrong with this? Image[] images = new Image[35]; for(int i = 0; i < 35; i++) { images[i] = new ImageIcon("res/" + (i + 1) + ".png").getImage(); }
A bit rusty on my java *faceplant* Oh my god, I totally forgot about that. I seem to be the only who's rusty on my Java
|
|
|
Logged
|
|
|
|
InfiniteStateMachine
|
|
« Reply #4856 on: June 12, 2015, 06:58:30 AM » |
|
bwar nested template spacing. Why you so crazy?
|
|
|
Logged
|
|
|
|
oahda
|
|
« Reply #4857 on: June 15, 2015, 12:42:06 PM » |
|
|
|
|
Logged
|
|
|
|
Martin 2BAM
|
|
« Reply #4858 on: July 04, 2015, 08:30:21 AM » |
|
Re C++ and initialisation:
I'd love to see default initialisation in C++. Ideally I think the default should be zero initialisation with uninitialised variables requiring specific declaration. There are some significant barriers to making this happen though.
Check C++11's class member initialization (at definition, not ctor) and default initialization via bracing: An empty pair of braces indicates default initialization. Default initialization of POD types usually means initialization to binary zeros, whereas for non-POD types default initialization means default construction: //C++11: default initialization using {} int n{}; //zero initialization: n is initialized to 0 int *p{}; //initialized to nullptr double d{}; //initialized to 0.0 char s[12]{}; //all 12 chars are initialized to '\0' string s{}; //same as: string s; char *p=new char [5]{}; // all five chars are initialized to '\0' class C { int x=7; //class member initializer public: C(); }; http://www.informit.com/articles/article.aspx?p=1852519I'm in love with C++11
|
|
|
Logged
|
|
|
|
|
|