南阳网站优化软件,设计模板主题为气流,佛山网站建设,17一起做网店普宁点击蓝字关注我们本文来自“The most stupid C bug ever”#xff0c;很有意思#xff0c;分享给大家。我相信这样的bug#xff0c;就算你是高手你也会犯的。你来看看作者犯的这个Bug吧。。首先#xff0c;作者想用一段程序来创建一个文件#xff0c;如果有文件名的话很有意思分享给大家。我相信这样的bug就算你是高手你也会犯的。你来看看作者犯的这个Bug吧。。首先作者想用一段程序来创建一个文件如果有文件名的话就创建真正的文件如果没有的话就调用tmpfile()创建临时文件。他这段程序就是HTTP下载的C程序。code200就是HTTP的返回码。else if (code 200) { // Downloading whole file/* Write new file (plus allow reading once we finish) */g fname ? fopen(fname, w) : tmpfile();
}但是这个程序只能在Unix/Linux下工作因为 Microsoft 的tmpfile()的实现居然选择了 C:\ 作为临时文件的存放目录这对于那些没有管理员权限的人来说就出大问题了。在Windows下就算你有管理员权限也会有问题。所以上面的程序在Windows平台下需要用不同的方式来处理不能直接使用Windows的tmpfile()函数。于是作者就先把这个问题记下来在注释中写下了FIXMEelse if (code 200) { // Downloading whole file/* Write new file (plus allow reading once we finish) */// FIXME Win32 native version fails here because// Microsofts version of tmpfile() creates the file in C:\g fname ? fopen(fname, w) : tmpfile();
}然后作者觉得需要写一个跨平台的编译FILE * tmpfile ( void ) {
#ifndef _WIN32return tmpfile();
#else//code for Windows;
#endif
}然后作者觉得这样实现很不好会发现名字冲突因为这样一来这个函数太难看了。于是他重构了一下他的代码——写一个自己实现的tmpfile() – w32_tmpfile然后在Windows 下用宏定义来重命名这个函数为tmpfile()。注这种用法是比较标准的跨平台代码的写法#ifdef _WIN32#define tmpfile w32_tmpfile
#endifFILE * w32_tmpfile ( void ) {//code for Windows;
}搞定编译程序运行。不是吧居然没有调用到我的w32_tmpfile()什么问题调试单步跟踪果然没有调用到难道是问号表达式有问题改成if – else 语句好了if(NULL ! fname) {g fopen(fname, w);
} else {g tmpfile();
}问号表达式不应该有问题吧难道我们的宏对问号表达式不起作用这难道是编译器的预编译的一个bug作者怀疑到。现在我们把所有的代码连在一起看并比较一下能正常工作的代码#ifdef _WIN32
# define tmpfile w32_tmpfile
#endifFILE * 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// Microsofts version of tmpfile() creates the file in C:\//g fname ? fopen(fname, w) : tmpfile();if(NULL ! fname) {g fopen(fname, w);} else {g tmpfile();}
}不能正常工作的代码#ifdef _WIN32
# define tmpfile w32_tmpfile
#endifFILE * 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// Microsofts version of tmpfile() creates the file in C:\g fname ? fopen(fname, w) : tmpfile();
}也许你在一开始就看到了这个bug但是作者没有。所有的问题都出在注释上/* Write new file (plus allow reading once we finish) */
// FIXME Win32 native version fails here because
// Microsofts version of tmpfile() creates the file in C:\你看到了最后那个C:\吗在C中“\” 代表此行没有结束于是后面的代码也成了注释。这就是这个bug的真正原因而之所以改成if-else能工作的原因是因为作者注释了老的问号表达式的代码所以那段能工作的代码成了/* Write new file (plus allow reading once we finish) */
// FIXME Win32 native version fails here because Microsofts version of tmpfile() creates the file in C: //g fname ? fopen(fname, w) : tmpfile();
if(NULL ! fname) {g fopen(fname, w);
} else {g tmpfile();
}我相信当作者找到这个问题的原因后一定会........最后我也share一个我很久以前犯的一个错。我有一个小函数需要传入一个int* pInt的类型然后我需要在我的代码里把这个int* pInt作除数。于是我的代码居然成了下面的这个样子float result num/*pInt;
….
/* some comments */
-x10 ? f(result):f(-result);因为我在我当时用vi编写代码所以没有语法高亮而我的程序都编译通过了但是却出现了很奇怪的事。我也不知道用gdb调式的时候发现有些语句直接就过了。这个问题让我花了很多时间最后发现问题原来是没有空格导致的下面我用代码高亮的插件来显示上面的代码float result num/*pInt;
..../* some comments */-x10 ? f(result):f(-result);我的代码居然成了float result num-x10 ? f(result):f(-result);我的这个错误在愚蠢程度上和上面那个作者出的错误有一拼吗*声明本文于网络整理版权归原作者所有如来源信息有误或侵犯权益请联系我们删除或授权事宜。戳“阅读原文”我们一起进步