В чем разница между (char *) 'r' и "r"?

Меня смущают различия между (char*)'r' и "r" и, возможно, (char*)"r", если это отличается от "r".

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

Этот формат для передачи аргумента режима fopen не вызовет предупреждения / ошибки моей eclipse IDE. Однако файл не будет правильно прочитан. С другой стороны, передача "r" или (char*)"r" приведет к правильному чтению.

1
0
78
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

(char*)'r' - это попытка преобразовать константу int'r' в указатель char*. Это фактическое значение, связанное с 'r', зависит от кодирование, используемого вашей системой.

Когда библиотечная функция пытается установить разыменование для этого указателя, поведение программы будет неопределенный.

"r", с другой стороны, является типом char[2], который будет разлагаться на указатель char*, необходимый для функции.

Среде IDE сложно выдать предупреждение в неправильном случае; и помните, что один из принципов C состоит в том, что вы предполагаете, что знаете, что делаете!

Нет, в C это нормально, хотя вам нужно явное приведение. У @Lundin есть отличный FAQ по этому поводу.

Bathsheba 10.09.2018 11:22
(char*)'r' может вызвать UB (он определяется реализацией и может быть смещен и / или отображать ловушку).
M.M 10.09.2018 11:24

В FAQ см. stackoverflow.com/questions/52186834/…

Bathsheba 10.09.2018 11:24

... что согласуется с тем, что я только что сказал

M.M 10.09.2018 11:26

@ M.M Вы согласны с тем, что (int*)'r' безопасен? (Действительно, вы знаете лучше меня по этим вопросам.)

Bathsheba 10.09.2018 11:27

@Bathsheba нет, это может вызвать UB (он определяется реализацией и может быть смещен и / или представлять ловушку - как объяснено на странице, на которую вы ссылаетесь)

M.M 10.09.2018 11:28

Хотя версия (char *) не будет смещена (char имеет выравнивание 1), это все равно может быть ловушкой

M.M 10.09.2018 11:29

Спасибо за помощь вам двоим, а также за ответы на часто задаваемые вопросы.

joeynoodles 11.09.2018 10:06

В C все символьные литералы на самом деле являются значениями int. Для систем, использующих систему кодирования ASCII (подавляющее большинство), тогда 'r' равен 114.

Итак, ваш призыв действительно openFile(&fp, fileNameOriginal, (char*)114);, и даже новичок должен увидеть, что это не совсем правильно.

Спасибо, в этом есть смысл.

joeynoodles 11.09.2018 10:08

Другие вопросы по теме