-1

I'm confused at the differences between (char*)'r' and "r", and perhaps (char*)"r", if that's different from "r".

int main () {
    char fileNameOriginal[MAXLINE] = "test.txt";
    openFile(&fp, fileNameOriginal, (char*)'r');
}
openFile(FILE **fp, char fileName[], char* mode) {
    *fp = fopen(fileName, mode);
}

This format for passing the mode argument of fopen will not cause a warning/error by my eclipse IDE. However, the file will not be read correctly. On the other hand, passing "r" or (char*)"r" will generate a correct reading.

Azeem
  • 11,148
  • 4
  • 27
  • 40

2 Answers2

6

(char*)'r' is a an attempt to convert the int constant 'r' to a char* pointer. That actual value associated with 'r' depends on the encoding your system uses.

When the library function attempts to dereference that pointer, the program behaviour will be undefined.

"r" on the other hand is a char[2] type, which will decay to a char* pointer required by the function.

It's difficult for an IDE to issue a warning for the incorrect case; and remember that one of the tenets of C is that you are assumed that you know what you're doing!

Bathsheba
  • 231,907
  • 34
  • 361
  • 483
  • 1
    No, that's fine in C, although you do need the explicit cast. @Lundin has an excellent FAQ on this. – Bathsheba Sep 10 '18 at 09:22
  • `(char*)'r'` might cause UB (it's implementation-defined and could be misaligned and/or a trap respresentation – M.M Sep 10 '18 at 09:24
  • 1
    On the FAQ, see https://stackoverflow.com/questions/52186834/pointer-from-integer-integer-from-pointer-without-a-cast-issues/52186835#52186835 – Bathsheba Sep 10 '18 at 09:24
  • ...which agrees with what I just said – M.M Sep 10 '18 at 09:26
  • @M.M Do you agree that `(int*)'r'` is safe? (Indeed your knowledge is better than mine on these issues.) – Bathsheba Sep 10 '18 at 09:27
  • @Bathsheba no, it might cause UB (it's implementation-defined and could be misaligned and/or a trap respresentation -- as explained by the page you linked) – M.M Sep 10 '18 at 09:28
  • Although the `(char *)` version wouldn't be misaligned (char has alignment 1), it could still be a trap – M.M Sep 10 '18 at 09:29
  • Thanks for the help you two, as well as the FAQ. – joeynoodles Sep 11 '18 at 08:06
4

In C all character literals are really int values. For systems using the ASCII encoding system (the vast majority) then 'r' is equal to 114.

So your call is really openFile(&fp, fileNameOriginal, (char*)114);, and even a beginner should see that it's not really correct.

Some programmer dude
  • 400,186
  • 35
  • 402
  • 621