На странице плагина matchit
написано:
Убедитесь, что в вашем файле vimrc
есть строка типа
:filetype plugin on
. Это позволяет подключать плагины типов файлов, многие из которых сообщают matchit.vim
, какие подходящие пары использовать.
Думаю, это потому, что альтернатива была хуже. Предположим, что прототип был изменен на добавление 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 *
,
У меня есть компилятор, который обеспечивает при компиляции в режиме C ++:
extern "C" {
long int strtol(const char *nptr, const char **endptr, int base);
long int strtol(char *nptr, char **endptr, int base);
}
Очевидно, что оба они разрешаются в один и тот же символ времени компоновки.
РЕДАКТИРОВАТЬ: согласно стандарту C ++ это заголовок не должен компилироваться. Я предполагаю, что компилятор просто не проверял это. На самом деле определения действительно появляются в системных заголовочных файлах.
Да, и другие функции имеют ту же проблему "отмывания констант" (например, 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);
'const char *' для первого аргумента означает, что strtol ()
не будет изменять строку.
То, что вы делаете с возвращенным указателем, является вашим бизнес.
Да, это можно рассматривать как нарушение типовой безопасности; C ++, вероятно, будет действовать по-другому (хотя, насколько я могу судить, ISO / IEC 14882: 1998 определяет
с той же подписью, что и в C).