cast отбрасывает квалификаторы из целевого типа указателя?

-Wcast-qual выводит это предупреждение в строке return функции stristr(). В чем проблема ?

предупреждение: приведение отбрасывает квалификаторы из типа цели указателя

char *stristr(const char *string, const char *substring)
{
size_t stringlength = strlen(string);
char *stringlowered = malloc(stringlength + 1);
strcpy(stringlowered, string);
tolower2(stringlowered); // in my source it has a different name, sorry.

char *substringlowered = malloc(strlen(substring) + 1);
strcpy(substringlowered, substring);
tolower2(substringlowered); // in my source it has a different name, sorry.

const char *returnvalue = strstr(stringlowered, substringlowered);
if(returnvalue != NULL)
{
    size_t returnvaluelength = strlen(returnvalue);
    returnvalue = string;
    returnvalue += stringlength - returnvaluelength;
}

free(stringlowered);
free(substringlowered);

return (char *)returnvalue;
}

EDIT:
В исходном коде glibc 2.15 strstr():

return (char *) haystack_start; // cast to (char *) from const char *

gcc c
person Nigel Ridley    schedule 16.04.2012    source источник
comment
Вы можете проверить, нет ли на вашей платформе strcasestr() доступных для вас.   -  person Michael Burr    schedule 17.04.2012


Ответы (3)


Вы объявили returnvalue в качестве указателя на const char, но затем привели его к указателю на не-const char. Вы отбросили квалификатор const, поэтому компилятор жалуется, что вы его отбросили!

Решение состоит в том, чтобы либо изменить возвращаемый тип функции, либо найти не-const char для указания. В вашей функции его нет, поэтому вы можете рассмотреть возможность изменения типа аргумента, если вам действительно нужен возвращаемый тип, отличный от const.

person Oliver Charlesworth    schedule 16.04.2012
comment
Прототип точно такой же, как исходный код стандартного C strstr(), который выдает тонны discards qualifiers предупреждений. Я предполагаю, что единственное решение состоит в том, чтобы сделать string, а не const. - person Nigel Ridley; 17.04.2012
comment
@NigelRidley: Ну, нет ни одной стандартной реализации C, но я полагаю, что ядро ​​​​большинства библиотек C было реализовано задолго до того, как произошла стандартизация языка. Следовательно, сомнительный код, если вы посмотрите вглубь! Также стоит иметь в виду, что библиотеки обычно пишутся авторами компилятора, поэтому они могут делать всевозможные кладжи, которые в противном случае были бы сомнительными/определяемыми реализацией/неопределенными. - person Oliver Charlesworth; 17.04.2012

Вы преобразуете const char * (назовем это немодифицируемой строкой) в char * (модифицируемую строку), отбрасывая квалификатор const.

person MByD    schedule 16.04.2012
comment
вам, вероятно, следует изменить возвращаемое значение на const char * и удалить приведение. - person MByD; 17.04.2012
comment
Прототип точно такой же, как и у стандартной функции C strstr(). - person Nigel Ridley; 17.04.2012
comment
@Nigel: стандартный C strstr() будет делать то же самое, что и const, что и вы, - просто библиотека не компилируется во время вашей сборки, поэтому предупреждение там давно исчезло (на самом деле я уверен, что оно даже не включено для сборка библиотеки). Возможно, вам придется отключить это конкретное предупреждение при создании функции stristr(), если вы хотите, чтобы она имела то же свойство, что и стандартная библиотека, возвращая неконстантный указатель в строку с константным указателем (и, следовательно, возлагая ответственность на пользователю, чтобы избежать неправильного действия с указателем). - person Michael Burr; 17.04.2012

Попробуйте изменить объявление/назначение

const char *returnvalue = strstr(stringlowered, substringlowered);

to

char *returnvalue = strstr(stringlowered, substringlowered);

а потом убрать заброс в обратку (она вам больше не нужна).

person EBlake    schedule 07.05.2015