Стертол, strtod небезопасен?

На странице плагина matchit написано:

Убедитесь, что в вашем файле vimrc есть строка типа

:filetype plugin on

. Это позволяет подключать плагины типов файлов, многие из которых сообщают matchit.vim, какие подходящие пары использовать.

15
задан user102008 14 June 2009 в 20:36
поделиться

4 ответа

Думаю, это потому, что альтернатива была хуже. Предположим, что прототип был изменен на добавление const :

long int strtol(const char *nptr, const char **endptr, int base);

Теперь предположим, что мы хотим проанализировать неконстантную строку:

char str[] = "12345xyz";  // non-const
char *endptr;
lont result = strtol(str, &endptr, 10);
*endptr = '_';
printf("%s\n", str);  // expected output: 12345_yz

Но что происходит, когда мы пытаемся скомпилировать этот код? Ошибка компилятора! Это довольно неинтуитивно, но вы не можете неявно преобразовать char ** в const char ** . См. C ++ FAQ Lite для подробного объяснения причин. Технически здесь говорится о C ++, но аргументы одинаково верны и для C. В C / C ++ вам разрешено только неявно преобразовывать из «указателя на тип в» указатель на const type "на самом высоком уровне: вы можете выполнить преобразование из char ** в char * const * ,

14
ответ дан 1 December 2019 в 03:15
поделиться

У меня есть компилятор, который обеспечивает при компиляции в режиме C ++:

extern "C" {
long int strtol(const char *nptr, const char **endptr, int base);
long int strtol(char *nptr, char **endptr, int base);
}

Очевидно, что оба они разрешаются в один и тот же символ времени компоновки.

РЕДАКТИРОВАТЬ: согласно стандарту C ++ это заголовок не должен компилироваться. Я предполагаю, что компилятор просто не проверял это. На самом деле определения действительно появляются в системных заголовочных файлах.

1
ответ дан 1 December 2019 в 03:15
поделиться

Да, и другие функции имеют ту же проблему "отмывания констант" (например, strchr, strstr, все такое).

Именно по этой причине C ++ добавляет перегрузки (21.4: 4 ): сигнатура функции strchr (const char *, int) заменяется двумя объявлениями:

const char* strchr(const char* s, int c);
      char* strchr(      char* s, int c);

Но, конечно, в C вы не можете иметь обе версии с одинаковым именем, корректные по константе, поэтому вы получите компромисс с неверной константой.

В C ++ не упоминаются аналогичные перегрузки для strtol и strtod, и действительно, в моем компиляторе (GCC) их нет. Не знаю, почему: тот факт, что вы не можете неявно преобразовать char ** в const char ** (вместе с отсутствием перегрузки), объясняет это для C, но я не совсем понимаю, что было бы не так с перегрузкой C ++:

long strtol(const char*, const char**, int);
7
ответ дан 1 December 2019 в 03:15
поделиться

'const char *' для первого аргумента означает, что strtol () не будет изменять строку.

То, что вы делаете с возвращенным указателем, является вашим бизнес.

Да, это можно рассматривать как нарушение типовой безопасности; C ++, вероятно, будет действовать по-другому (хотя, насколько я могу судить, ISO / IEC 14882: 1998 определяет с той же подписью, что и в C).

1
ответ дан 1 December 2019 в 03:15
поделиться
Другие вопросы по тегам:

Похожие вопросы: