Article count:1382 Read by:1966155

Account Entry

The stupidest BUG in the history of embedded C language

Latest update time:2023-12-06 07:00
    Reads:
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

【Album】 ARM
【Album】 Fans Q&A
Album Introduction to linux
Album Computer Network
Album Linux driver


Featured Posts


Latest articlesabout

 
EEWorld WeChat Subscription

 
EEWorld WeChat Service Number

 
AutoDevelopers

About Us About Us Service Contact us Device Index Site Map Latest Updates Mobile Version

Site Related: TI Training

Room 1530, Zhongguancun MOOC Times Building,Block B, 18 Zhongguancun Street, Haidian District,Beijing, China Tel:(010)82350740 Postcode:100190

EEWORLD all rights reserved 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2021 EEWORLD.com.cn, Inc. All rights reserved