The stupidest BUG in the history of embedded C language
Click on the blue " Linux " in the upper left corner and select " Set as Star "
This article comes from "The most stupid C bug ever". It is very interesting and I would like to share it with you.
I believe that even if you are a master, you will make such a bug. Let’s take a look at this bug made by the author. .
First, the author wants to use a program to create a file. If there is a file name, the real file will be created. If not, tmpfile() will be called to create a temporary file.
This program is a C program for HTTP download. code==200 is the HTTP return code.
else if (code == 200) { // Downloading whole file
/* Write new file (plus allow reading once we finish) */
g = fname ? fopen(fname, "w+") : tmpfile();
}
However, this program can only work under Unix/Linux, because the implementation of Microsoft's tmpfile() actually chooses C:\ as the storage directory for temporary files, which is a big problem for those who do not have administrator rights. . Under Windows 7, there will be problems even if you have administrator rights.
Therefore, the above program needs to be processed in different ways under the Windows platform, and the Windows tmpfile() function cannot be used directly.
So the author first wrote down this problem and wrote FIXME in the comments:
else if (code == 200) { // Downloading whole file
/* Write new file (plus allow reading once we finish) */
// FIXME Win32 native version fails here because
// Microsoft's version of tmpfile() creates the file in C:\
g = fname ? fopen(fname, "w+") : tmpfile();
}
Then, the author felt the need to write a cross-platform compilation:
FILE * tmpfile ( void ) {
#ifndef _WIN32
return tmpfile();
#else
//code for Windows;
#endif
}
Then, the author feels that this implementation is not good, and there will be name conflicts, because the function will be too ugly.
So he refactored his code - wrote a self-implemented tmpfile() - w32_tmpfile, and then used a macro definition to rename this function to tmpfile() under Windows. (Note: This usage is a relatively standard way of writing cross-platform code)
#ifdef _WIN32
#define tmpfile w32_tmpfile
#endif
FILE * w32_tmpfile ( void ) {
//code for Windows;
}
Done! Compile the program and run it.
Depend on! My w32_tmpfile() is not called. What's the problem? Debugging, single-step tracing, and sure enough it was not called!
Is there something wrong with the question mark expression? Change it to an if – else statement, and there you go!
if(NULL != fname) {
g = fopen(fname, "w+");
} else {
g = tmpfile();
}
There shouldn't be a problem with the question mark expression, right? Could it be that our macro doesn't work on the question mark expression? Is this a pre-compilation bug of the compiler? The author doubts it.
Now let's look at all the code together and compare:
code that works
#ifdef _WIN32
# define tmpfile w32_tmpfile
#endif
FILE * w32_tmpfile ( void ) {
code for Windows;
}
else if (code == 200) { // Downloading whole file
/* Write new file (plus allow reading once we finish) */
// FIXME Win32 native version fails here because
// Microsoft's version of tmpfile() creates the file in C:\
//g = fname ? fopen(fname, "w+") : tmpfile();
if(NULL != fname) {
g = fopen(fname, "w+");
} else {
g = tmpfile();
}
}
Code that doesn't work properly
#ifdef _WIN32
# define tmpfile w32_tmpfile
#endif
FILE * w32_tmpfile ( void ) {
code for Windows;
}
else if (code == 200) { // Downloading whole file
/* Write new file (plus allow reading once we finish) */
// FIXME Win32 native version fails here because
// Microsoft's version of tmpfile() creates the file in C:\
g = fname ? fopen(fname, "w+") : tmpfile();
}
Maybe you saw the bug at the beginning, but the author didn't. All the problems are in the annotations:
/* Write new file (plus allow reading once we finish) */
// FIXME Win32 native version fails here because
// Microsoft's version of tmpfile() creates the file in C:\
Did you see that C:\ at the end? In C, "\" means that the line has not ended, so the following code also becomes a comment. This is the real cause of this bug !
The reason why the change to if-else works is because the author commented the old question mark expression code, so the working code became:
/* Write new file (plus allow reading once we finish) */
// FIXME Win32 native version fails here because Microsoft's version of tmpfile() creates the file in C: //g = fname ? fopen(fname, "w+") : tmpfile();
if(NULL != fname) {
g = fopen(fname, "w+");
} else {
g = tmpfile();
}
I believe that when the author finds the cause of this problem, he will definitely say "damn it"! I also believe that this bug cost the author a lot of time!
Finally, I also share a mistake I made before.
I have a small function that needs to pass in an int* pInt type, and then I need to divide this int* pInt in my code. So my code became like this:
float result = num/*pInt; ….
/* some comments */
-x<10 ? f(result):f(-result);
Because I used vi to write the code at the time, there was no syntax highlighting, and my program was compiled and passed, but something strange happened.
I don't know either. When using gdb to debug, I found that some statements passed directly.
This problem cost me a lot of time, and finally I found that the problem was caused by the lack of spaces, TNND. Next, I used the code highlighting plug-in to display the above code.
float result = num/*pInt;
....
/* some comments */
-x<10 ? f(result):f(-result);
Holly Shit! My code became:
float result = num-x<10 ? f(result):f(-result);
Oh shit! My mistake is as stupid as the one made by the author above.
From: CoolShell - CoolShell
Link: https://coolshell.cn/articles/5388.html
Original text: https://www.elpauer.org/2011/08/the-most-stupid-c-bug-ever/
end
A mouthful of Linux
Follow and reply [ 1024 ] Massive Linux information will be given away
Collection of wonderful articles
Article recommendation
Featured Posts