2016-01-17 4 views
3

Компиляция заданного образца кода с gcc/g ++ завершается успешно. Нет ошибки для вызова strchr, который, очевидно, присваивает const char *char *.Почему C стандартная библиотечная функция `strchr` возвращает указатель на не-const, если задано` const char * `как первый аргумент?

Я нашел strchr объявлен char * strchr(const char *, int) на двух различных источников pubs.opengroup.org и cplusplus.com

Если strchr реализуется как откинуть константность, то почему это так?

Если цель состояла в том, чтобы обеспечить функцию, которая работает как на строках char *, так и на const char * - это могло быть реализовано с использованием двух разных имен функций.

Можете ли вы дать более подробное объяснение этому.

#include <string.h> 

int main() { 
    const char *str = "Sample string"; 
    char * ptr; 

    //ptr = str;   // Error: discards const qualifier - both on gcc and g++ 
    pch = strchr(str,'S'); // Succeeds in assigning <const char *> to <char *> 

    *pch = '4';    // Runtime error: segmentation fault 

    return 0; 
} 

Пробовали на Win7 с помощью MSYS2/MinGW-w64 gcc_v5.3.0 и TDM-gcc32 v5.1.0.

+0

Возможный дубликат [Как работает реализация strchr] (http://stackoverflow.com/questions/14367727/how-does-strchr-implementation-work) – Kninnug

ответ

8

Когда вы звоните strchr с char*, вы хотите вернуть char* так, чтобы вам не нужно было делать результаты. C не поддерживает перегрузку функции, поэтому одна и та же функция strchr используется для поиска в char* и в const char*. Во всех случаях он возвращает указатель не const. Если вы вызываете его с помощью const char*, он в основном отбрасывает const, поэтому ответственным за его использование является безопасное использование (например, путем назначения результата const char*, чтобы избежать любого небезопасного использования возвращаемого указателя).

Если целью было предоставить функцию, которая работает как на символах char *, так и const char *, она могла бы быть реализована с использованием двух разных имен функций.

Да, возможно, это было так, но это не так. Исходная версия C вообще не поддерживала const, поэтому разработчик всегда был обязан избегать попыток изменить строковые литералы. Если были использованы разные имена функций, это привело бы к нарушению существующего кода, который бы безопасно использовал strchr. Было бы замедлили принятие нового const ключевого слова, если традиционный код C, как это вдруг перестал компиляции:

char arr[] = "foo bar"; 
*strchr(arr, 'r') = 'z'; 

«Дух С» является то, что он не пытается остановить вас делать опасные вещи, это ваш задание написать правильный код.

В C++ strchr перегружен сохранить константность:

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

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

 Смежные вопросы

  • Нет связанных вопросов^_^