Skip to main content
GameDev.net gamedev.net
🔒 Locked

C++ Bug????

Started by nivlekio Mar 1, 2008 at 1:56 PM 26 replies 3.4k views
Original Post
nivlekio
nivlekio
I was working on networking and i made a silly mistake.
Quote:
while(1); { cout << "In while Loop" << endl if(argument) { code........ } else { break; } }
As you can see there is a semi colon after the while command. Some how this made the program loop forever at the while(1) bit and not execute the code in the braces. I know this becuase it did not print out the "In while Loop" string. But after i noticed this mistake ( 2hrs later :( ) i took off the semi colon and the program entered the while loop braces and executed the code. then it broke out of it then the if statement was false. Seeing i did not get an error from the compiler why would some one want to do this if its proper c++ code?
ToohrVyk
ToohrVyk
size_t strlen(const char *s){  size_t i = 0;  while (s[i++] != '\0');  return i - 1;}
nivlekio
nivlekio
ah kk mmm did not know you could do that thanks
Crypter
Crypter
Quote:
Some how this made the program loop forever at the while(1) bit and not execute the code in the braces. I know this becuase it did not print out the "In while Loop" string.

Of course, because while(1); is an infinity loop.

Quote:
Seeing i did not get an error from the compiler why would some one want to do this if its proper c++ code?


Because C and C++ do not have any strict rules on how you format your code. ; is used to end a statement (in your case, while(1)), which has caused the infinity loop.

Because there is no strict formatting rules, it allows us to write a given statement different ways.

Also, because { and } are used for creating a new local scope, there is no errors in your code--with or without the semicolen (;).
dascandy
dascandy
Newer versions of GCC warn on this kind of construct as it's very dangerous and easily overlooked. Have found this bug in somebody elses &#106avascript as well.<br><br>GCC now requires you (if you enable the warnings) to write<br><br>while(1) {}<br><br>as it will refuse the semicolon for such use.
c_olin
c_olin
I've often seen such statements coded as:

while(statement_is_true)    ;


It makes it look more like an if statement with one following line without braces. Just a blank line in this case.

Although a lot of people aren't so fond of using whiles or ifs without any braces. Which makes sense. Not using braces has hurt me before. (Well I guess I hurt myself because I wasn't paying attention).
staticVoid2
staticVoid2
Quote:
Original post by ToohrVyk
size_t strlen(const char *s){  size_t i = 0;  while (s[i++] != '\0');  return i - 1;}


size_t strlen(const char *s){  size_t i = 0;  while (s != 0) i++;  return i;}


faster?
ToohrVyk
ToohrVyk
void strcpy(char *d, const char *s){  while (*d++ = *s++);}
Evil Steve
Evil Steve
Quote:
Original post by staticVoid2
Quote:
Original post by ToohrVyk
size_t strlen(const char *s){  size_t i = 0;  while (s[i++] != '\0');  return i - 1;}


*** Source Snippet Removed ***

faster?
It'll generate the exact same assembly, so no.
staticVoid2
staticVoid2
just a thought, because it had one less loop and one less subtract.
swiftcoder
swiftcoder
Quote:
Original post by staticVoid2
Quote:
Original post by ToohrVyk
size_t strlen(const char *s){  size_t i = 0;  while (s[i++] != '\0');  return i - 1;}

size_t strlen(const char *s){  size_t i = 0;  while (s != 0) i++;  return i;}

faster?

How about with a pre-increment for those elusive extra cycles... [grin]
size_t strlen(const char *s){  size_t i = -1;  while (s[++i] != 0);  return i;}
Tristam MacDonald. Ex-BigTech Software Engineer. Future farmer. [https://trist.am]
Sneftel
Sneftel
How 'bout we just use the strlen that came with the compiler, which is implemented in carefully hand-tuned assembly and is blazingly fast.
swiftcoder
swiftcoder
Quote:
Original post by Sneftel
How 'bout we just use the strlen that came with the compiler, which is implemented in carefully hand-tuned assembly and is blazingly fast.

Because that wouldn't be nearly as much fun [smile]

*runs off to hide in the corner*
Tristam MacDonald. Ex-BigTech Software Engineer. Future farmer. [https://trist.am]
guardian24
guardian24
Quote:
How about with a pre-increment for those elusive extra cycles...

Postincrement will be optimized by the compiler automatically for builtin types, as per Sutter.
TheGilb
TheGilb
Let's be brutally honest here .. the built in strlen is fast enough for any situation you can think of; and trusting your compiler to generate better code than hand tuned assembly is madness. No offense. :-) Though if you want to take it to the next level then let's start another thread and lay some hard performance metrics down comparing the strlen provided by your favourite compiler vendor and our own implementations :-) Otherwise, let's just leave poor old strlen alone, what did he ever do to you anyway?
speciesUnknown
speciesUnknown
I've been programming on and off for 12 years and have seen a grand total of 4 genuine, verified bugs in interpreters / compilers. The other 1.2E97 errors were my fault.

Still, its fair to say that while(); should not be standard, and should at the very least generate a warning, but that is a design choice and not a "bug" as such.
Don't thank me, thank the moon's gravitation pull! Post in My Journal and help me to not procrastinate!
osmanb
osmanb
Quote:
Original post by speciesUnknown
I've been programming on and off for 12 years and have seen a grand total of 4 genuine, verified bugs in interpreters / compilers. The other 1.2E97 errors were my fault.


You're lucky. I've seen dozens, and I've personally tracked down at least 10 (producing reliable test-cases for the vendors). The joys of console development.
frob
frob
Quote:
Original post by osmanb
Quote:
Original post by speciesUnknown
I've been programming on and off for 12 years and have seen a grand total of 4 genuine, verified bugs in interpreters / compilers. The other 1.2E97 errors were my fault.


You're lucky. I've seen dozens, and I've personally tracked down at least 10 (producing reliable test-cases for the vendors). The joys of console development.


I've also tracked down a few from vendors over the years. They are rare but they do happen. The smaller the audience the more likely you are to find them, which is why console and embedded programmers complain so much about the low quality of the tools. Almost everything I've seen over the last five or eight years has been many orders of magnitude better than the older compilers. We used to just have the AT&T c++ specs to claim violations, but often those cries fell on deaf ears. Being able to point at an ISO standard has really helped every serious compiler out there.

Just beware.

Unless you have real proof that it is wrong, don't go blaming the compiler.

Remember that thousands or tens-of-thousands of people around the globe are using those tools. The odds of you discovering a major bug are extremely small. It is much more likely that it is a fault in your own code. If you are saying something like "The STL is broken" you are probably wrong. If it is something like "a particular combination of function pointers inside an anonymous union doesn't seem to work properly", then you may be on to something.


In the case of a crash, you should be prepared with output of an actual compiler crash or ICE along with source that they can use to reproduce it. Those are easy to spot.

Often people claim: "You have a bug that such-and-such didn't do what I expected". They are often immediately countered with short replies like: "See the language standard, section 6.x.y paragraph 4. The behavior you saw is correct." When you make a claim, you better be able to show exactly what the problem is, a short code sample that demonstrates it, and the exact place in the language standard that says it is wrong.

In the case of debug vs released/optimized code, it is often harder to prove a compiler error. You have to prove that your optimizations were incorrectly applied, and not the result of a correctly acting but misapplied optimizer. The most common non-bug I've seen is aggressive dead code removal -- if you aren't directly accessing a function the optimizer may (legitimately) see it as dead code and remove it. When you start getting fancy with the language, carefully watch the verbose compiler and linker outputs before claiming it is a bug.


It's okay to claim you found a bug. Just be prepared to prove it.
UziMonkey
UziMonkey
This is indeed legal code. In C, the semicolon is used to terminate all expressions but it's also used alone as the empty expression. As pointed out by others, there are indeed "useful" applications of the empty expression and the while statement but it's more often a typo. Even if it's not a typo, it's misleading and cryptic syntax that should at least generate a warning.

MSVC++ 2008 doesn't generate a warning even on warning level 4. It does generate a warning about while(1) itself though, apparently conditional expressions shouldn't be constants. If you want to use infinite loops on warning level 4, I guess you have to use for(;;).

To answer questions like this, it's usually best to go to raw information. That information being the ANSI C standard or a C grammar in this case.
exwonder
exwonder
Quote:
Original post by osmanb
You're lucky. I've seen dozens, and I've personally tracked down at least 10 (producing reliable test-cases for the vendors). The joys of console development.


Ahh I was skeptical until I saw the username! We don't know each other, but as of recently I work for the same company as you (large version), and I've long been a fan of your posts on platform support groups. (It's possible you'd recognize my real name in the same way, but it's hard to say.)

Nice to know that you post here as well.

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.