C++ and games programming: the Wesnothian Approach

Discuss the development of other free/open-source games, as well as other games in general.

Moderator: Forum Moderators

szopen
Posts: 631
Joined: March 31st, 2005, 12:51 pm

Post by szopen »

aelius wrote:

Code: Select all


for(int i=1; i < 10; i++);
{
  ...a bunch of stuff...
}
- b.
Hehe, this is exactly what I am giving to my students and when they became frustrated (You can't lowered me mark only because I missed that one semicolon!) i answer that lowered mark today may save them a lot of frustration tomorrow :)
User avatar
allefant
Units Database Administrator
Posts: 516
Joined: May 6th, 2005, 3:04 pm

Post by allefant »

One stupid thing I did several times in one form or another was using wrong types, like this:

Code: Select all

unsigned int r = 1;
float x = 10;
x = x + (r - 2);


There was often something like this hidden deep in other code, and I think the time I spent hunting such stuff amounts to days. If just g++ would spit out a warning :P

And one other very embarassing thing for me is when I forget to initialize some class members, as I already mentioned. Usually I have one constructor who intializes everything, and maybe some others who do too, and just one of them forgets one variable. The program might now run fine a lot of times (since the variable got sane values), just sometimes it doesn't work since the varaible has wrong values. This one is by far my number one time consuming bug (probably because I'm used to C, where you allocate with calloc and therefore everything is initialized to 0).
User avatar
Jetrel
Posts: 7242
Joined: February 23rd, 2004, 3:36 am
Location: Midwest US

Post by Jetrel »

allefant wrote:One stupid thing I did several times in one form or another was using wrong types, like this:

Code: Select all

unsigned int r = 1;
float x = 10;
x = x + (r - 2);


There was often something like this hidden deep in other code, and I think the time I spent hunting such stuff amounts to days. If just g++ would spit out a warning :P
When you have something like the error that happens here, which is an unsigned int going out of the bounds of what it is supposed to hold, what is supposed to happen?

Is this defined anywhere in the standard?
torangan
Retired Developer
Posts: 1365
Joined: March 27th, 2004, 12:25 am
Location: Germany

Post by torangan »

Yes, for modulo semantics are mandatory so unsigned(1) - 2 is MAX_UNSIGNED - 1. For int there's no definition by the standard (assuming MIN_INT - x) and the result does depend on the compiler / architecture / optimization level...
silene
Posts: 1109
Joined: August 28th, 2004, 10:02 pm

Post by silene »

torangan wrote:For int there's no definition by the standard (assuming MIN_INT - x) and the result does depend on the compiler / architecture / optimization level...
No, the behavior of integer overflow is explicitely described by the standard: it is undefined. If a detail of the language is present in the standard, it falls into one of these three categories: defined, implementation-defined, undefined. What you have described is an implementation-defined feature. But integer overflow is undefined. As a consequence, for MIN_INT - x, the answer is 42, and sorry for the inconvenience.

More seriously, "undefined" features are useful for compiler designer. For integer overflows, it means that if you add 1 to a positive integer, the compiler can assume it is still a positive integer. Indeed, either it is a positive integer, either there was an overflow, and an undefined integer could as well be a positive integer. This is incredibly useful when looking for loop invariants when compiling.
torangan
Retired Developer
Posts: 1365
Joined: March 27th, 2004, 12:25 am
Location: Germany

Post by torangan »

Well, I didn't say anything else, did I? I know that it's undefined but that simply means what I wrote. There's no definition in the standard what the result will be. It'll be consistent in a specific situation but there are no guarantees at all once you change architecture, compiler, optimizations... Usually it'll be what your hardware makes out of it but like you wrote, the compiler is free to assume that it'll never overflow while doing optimizations.
Talking in standard terms isn't very usefull to the casual user and especially undefined is somewhat hard to grasp for most users. Obviously it's clearly defined to be undefined :wink: but I think - expect the result to be random is the most usefull for the user. It's rather unlikely that it'll cause the program to abort but that would of course be an absolutely correct implementation!
freecraft
Posts: 94
Joined: April 28th, 2005, 12:49 am
Location: Serbia
Contact:

Post by freecraft »

Stupid mistake:

Code: Select all

#... includes

#ifdef UNIX
  char* path ="/root/newapp/.config";
#elseif MS_DOS
  char* path ="\root\newapp\.config";
#endif

int main() {
  std::cout<<"Opening config file ...\n"<<
  std::ifstream config(path);
  if (config.bad()) {
    std::cerr << "File not opened! What???\n";
    return -1;
  }
  cout<<"File is opened ...";
  return 0;
}
-- it is about c++ portable Unix/Dos application, got it from "How not to program in C++" book.
Breeblebox
Posts: 209
Joined: October 27th, 2004, 8:24 am
Location: New Zealand

Post by Breeblebox »

How responsive is ~100,000 LoC going to be running through an interpreter? The reality is, you could write Wesnoth in Javascript if you wanted, it just wouldn't pass the sanity check...

Oh, and I agree with torangan, using whitespace as a delimiting syntax is the craziest thing I ever heard.
Bear, as in Fozzy,Bare, as in Arms,Beer, as in Free.
Distro | Browser
silene
Posts: 1109
Joined: August 28th, 2004, 10:02 pm

Post by silene »

torangan wrote:I know that it's undefined but that simply means what I wrote. There's no definition in the standard what the result will be. It'll be consistent in a specific situation but there are no guarantees at all once you change architecture, compiler, optimizations...
No, you don't understand at all what "undefined" means.
What you are describing is an "implementation-defined" feature. Consider division by a negative number for example. It is "implementation-defined": the behavior is documented by the implementation. The result will be consistent once you have set the architecture and the compiler (and its options).
Integer overflow is not guaranteed to be consistent. I suggest you read the paragraph 1.3.12 [defns.undefined] of the standard, especially the part that talks about unpredictable results. Contrarily to what you seem to believe, "unpredictable" doesn't mean "consistent", even if you restrict yourself to a specific situation.
torangan
Retired Developer
Posts: 1365
Joined: March 27th, 2004, 12:25 am
Location: Germany

Post by torangan »

There's no gurantee that it'll be consistent for a given situation but it's extremly likely that running the same program with the same input multiple times will have the same result. If not, it's still correct because it's been undefined in the first place but you'd need some rather strange hardware to get completely unpredictable results. I know that the exact definition is even more loose but hardware tends to be somewhat predictable most of the time.
The simple rule is: never invoke undefined behaviour. Reality is: signed integer overflow is considered to be modulo by many programmers. :(
Post Reply