C fopen() fclose() pointers don't match


Quote:-
Though similar statements and concepts have been made over the course of history, the law itself was coined by, and named after, American aerospace engineer Edward A. Murphy Jr.; its exact origins are debated, but it is generally agreed it originated from Murphy and his team following a mishap during rocket sled tests some time between 1948 and 1949, and was finalized and first popularized by testing project head John Stapp during a later press conference. Murphy's original quote was the precautionary design advice that :-

"If there are two or more ways to do something and one of those results in a catastrophe, then someone will do it that way."
 
Hmm... I may have been unfair to Rust. Reading through this some more https://doc.rust-lang.org/reference/expressions/if-expr.html

I cannot find any way to assign a value to a variable within a conditional expression, unlike C.
Rust has a 'let...if' construct but that is not the same thing. So perhaps Rust has fixed it after all.

The language still has the C-style tokens - '==', '!=', etc, (so clearly it is still vulnerable to those being mistyped as '=', hence my initial reaction...), but the specific bug under discussion only occurs in C when those are mistyped as assignments inside a conditional expression. So perhaps Rust has fixed that one.

My knowledge of Rust is very limited so I may of course be wrong on this, it would be interesting if someone with a greater knowledge of Rust could confirm whether or not an assignment can be made to a variable within a conditional expression in Rust (disregarding let...if).

Is it legal to say something like
Code:
if (var = 10) {... ; }
in Rust?
 
The thing you're trying to protect against is accidentally typing '=' instead of the intended '==' or '!=' (or '<=' or '>='), which is a well-known classic bug in C. Or a random pigeon flying in through the window and pecking at the delete key when the cursor is under the '!' or '<' or '>' character. Pesky pigeons! Why is it a problem? Because the incorrect code will compile with no warnings!
For 30 years I have never made bug typing '=' instead of '=='. And again - there is warning message to protect you from such rare bug. Reading and writing 'if ( 5 < a )' is more significant risk of logical errors.
Trust me, when you're working on codebases of millions of lines of C code, those kinds of bugs are guaranteed to occur, and furthermore they will be a huge pain in the elbow to debug!
See FreeBSD (Linux kernel, etc.) source code and think how it works without =/== "protection".
 
OK, Linux kernel is bad code. Look in FreeBSD, MySQL/MariaDB, SQLite, OpenSSL or any other large project written in C. Maybe gcc and clang compilers cannot be bad code.
 
And again - there is warning message to protect you from such rare bug.
Which is only useful if one actually pays attention to compiler warnings or set compiler flags so "warnings are errors and cause compilation to stop".
In my roughly the same timeframe, not enough people actually pay attention to compiler warnings unless they are turned into errors. It's like doing initial builds with all optimization turned off (easier debugging) but subtle errors show up when optimization is turned on.
 
If I compile the following code on 14.3R,

C:
#include <stdio.h>

int main(int argc, char *argv[]) {
  int var;

  if ( var = 10 ) {
    printf("assigned var=10\n");
  }
}

The only warning I get pertaining to '==' says
" note: use '==' to turn this assignment into an equality comparison"

The message is only a 'note', ie informational, NOT a warning.

If I compile the same code with gcc on linux, I don't get ANY equivalent warning or 'note' about possible misuse of '==', including with -Wall.

The 'note' is pretty easily defeated. The following code compiles cleanly on freebsd 14.3R, and on linux, including with -Wall.
C:
#include <stdio.h>

int main(int argc, char *argv[]) {
  int var;

  if ( (var = 10) ) {
    printf("assigned var=10\n");
  }
}
 
And what? Double parenthesis syntax says this "I know this looks like incorrect assignment but it is not". Or maybe somebody will accidentally type 2 parenthesis and not see them? And later he/she will enter = instead of == and not see it?
 
This is his/her problem. Maybe better to program in python or javascript. C language requires some precision and attention on details.
I don't disagree with this, but a lot of times it's not isolated to an individual; sometimes it is institutional. "Need to get this product out the door so speed up dev as much as possible" and people that want to follow a better process are seen as "blockers".
 
And what? Double parenthesis syntax says this "I know this looks like incorrect assignment but it is not". Or maybe somebody will accidentally type 2 parenthesis and not see them? And later he/she will enter = instead of == and not see it?
It is a common construct to have a compound conditional expression where the sub-expressions are delineated by parentheses as a matter of style for readability, eg
if ( (cond expr a) && ( cond expr b) && (cond expr c)... )

So it's easy to fall into the trap, and you can save yourself from it by using a convention that avoids the bug in the first place.

Why is there any objection to using this idiom? What harm does it do?
 
I will repeat - writing things like if ( 5 < a ) is modern trend pretending it is "safe programming". And again - look at gcc/clang source code and think why their programmers don't use the trend. Maybe they are not good.
 
I will repeat - writing things like if ( 5 < a ) is modern trend pretending it is "safe programming". And again - look at gcc/clang source code and think why their programmers don't use the trend. Maybe they are not good.
No-one is saying write things like '(5 < a)', in fact I've never seen that in any code I've looked at! As for a modern trend... I've been writing code that way to mitigate the '=' is not '==' bug for decades. I haven't heard of this 'pretend safe programming in C' you talk about either; in fact I'm pretty sure I was taught this particular mitigation during my original C programming course at univ, back in the '80's.

Anyway, no matter.
 
Just for the OP's benefit... the example program I posted, modified to take account of 6502's objections, is listed beolw. Feel free to use whichever version you like, they are both equvalent.. :)
C:
#include <stdio.h>
#include <string.h>
#include <errno.h>

int main(int argc, char *argv[]) {
  int rc=-1;

  if (argc != 2) {  // changed order to keep 6502 happy
    fprintf(stderr, "Error: test <filename>\n");
  } else {
    FILE *fptr;

    fptr = fopen(argv[1], "r+");
    if (fptr != NULL) {   // changed order to keep 6502 happy
      printf ("opened file: %s\n", argv[1]);

      fclose (fptr);
      // strictly we should check the fclose return code here
      printf ("closed file: %s\n", argv[1]);
      rc = 0;
    } else {
      fprintf(stderr, "failed to open file: %s - %s\n",
          argv[1],
          strerror(errno));
    }
  }

  return rc;
}
 
There is compiler warning for this. It is stupid trend blindly followed by many people. Most stupid is to compare "if ( 5 < a )" instead of "if ( a > 5 )".
For the record, I've never had to suffer reading anyone doing 5<a. We're talking about equality comparison vs assignment here and how in C/C++ the mistake can slip thru if you don't reverse the operators like I suggest, but then I'm a dinosaur who is set in his ways.
 
Back
Top