Строковые литералы против const char * в C - PullRequest
10 голосов
/ 22 июля 2010

Почему компиляторы ANSI C не помечают использование строкового литерального аргумента в вызове функции, в котором соответствующий параметр не имеет спецификатора const? Например, следующий код может сгенерировать исключение при попытке записи в постоянную память.

void somefunc(char buffer[10]);

void somefunc(char buffer[10]) {
    int i;

    for (i = 0;   i < 10;   i++)
       buffer[i] = 0;
}

int main(int argc, char **argv) {

    somefunc("Literal");
    return 0;
}

Эта ситуация может быть идентифицирована во время компиляции, но VS2010 и gcc, похоже, этого не делают. Вызов somefunc с аргументом const char * вызовет предупреждение компилятора.

Ответы [ 5 ]

16 голосов
/ 22 июля 2010

Это наследство K & R. Его исправление сломало бы миллион программ.

11 голосов
/ 22 июля 2010

gcc: используйте флаг -Wwrite-strings

PS. Руководство gcc объясняет, почему это не является частью -Wall. В любом случае, как всегда, вы должны найти комбинацию флагов -W, которая соответствует вашим потребностям и стилю кодирования. Например, в недавнем проекте я использовал что-то вроде этого: -Werror -Wall -Wextra -Wformat=2 -Winit-self -Wswitch-enum -Wstrict-aliasing=2 -Wundef -Wshadow -Wpointer-arith -Wbad-function-cast -Wcast-qual -Wcast-align -Wwrite-strings -Wstrict-prototypes -Wold-style-definition -Wmissing-prototypes -Wmissing-declarations -Wredundant-decls -Wnested-externs -Winline -Wdisabled-optimization -Wunused-macros -Wno-unused

7 голосов
/ 22 июля 2010

Что сказал Ганс Пассант. const был добавлен как часть стандарта ANSI в 1989 году, поэтому все, что было до этого, не имело const.

6 голосов
/ 22 июля 2010

строковые литералы не являются константными в C;в C ++ они есть.

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

4 голосов
/ 22 июля 2010

Компилятор GNU (а также компилятор Intel C, iirc) выдаст предупреждение, если используется -Wwrite-string:

$ gcc -Wall -Wwrite-strings -o foo /tmp/foo.c
/tmp/foo.c: In function 'main':
/tmp/foo.c:12: warning: passing argument 1 of 'somefunc' discards qualifiers from pointer target type
/tmp/foo.c:3: note: expected 'char *' but argument is of type 'const char *'

Что касается VS2010, я не могу вам помочь.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...