Ответ 1
да, это совершенно безопасно и считается стандартной практикой. Строковые литералы гарантированы для нулевого завершения.
Мы все знаем, что переполнение проблемы может вызвать, и именно поэтому strn * существует - и большую часть времени они имеют смысл. Тем не менее, я видел код, который использует strncmp для сравнения параметров командной строки, например:
if(... strncmp(argv[i], "--help", 6) == 0
Теперь я бы подумал, что это необязательно и, возможно, даже опасно (для более длинных параметров было бы легко исключить символы в литерале).
strncmp останавливается на нулях, а код уже предполагает, что argv [i] имеет нулевое завершение. Любой строковый литерал гарантированно заканчивается на нуль, поэтому почему бы не использовать strcmp?
Возможно, я что-то пропустил, но я видел это несколько раз, и на этот раз он заинтриговал меня достаточно, чтобы спросить.
да, это совершенно безопасно и считается стандартной практикой. Строковые литералы гарантированы для нулевого завершения.
Вы уверены, что код не предназначен для соответствия
"--helpmedosoemthingwithareallylongoptionname"
?
Вы правы.
Кроме того, приведенный вами пример будет соответствовать "--help", но также и всему, что начинается с "--help" (например, "-help-me" ).
Редкий случай, когда чрезмерное == неправильное.
Насколько я знаю, вы абсолютно правы - нет причин использовать strncmp вместо strcmp. Возможно, люди просто переусердствовали (не обязательно плохо).
Как говорили другие, strcmp()
совершенно безопасен для использования с литералами. Если вы хотите использовать strncmp()
, попробуйте следующее:
strncmp(argv[i], "--help", sizeof("--help"))
Пусть компилятор сделает подсчет для вас!
Это будет соответствовать только точной строке "--help". Если вы хотите сопоставить все строки, начинающиеся с "--help"
(как это делает ваш код), используйте sizeof() - 1
, чтобы не включать последний '\0'
.
Да, наличие литерала ограничивает размер сравниваемых данных до размера литерала. Здесь stncmp избыточен.
Кто-то может сказать, что strncmp - хорошая привычка вступать, но это лишнее из-за проблемы подсчета символов.
Я бы, наверное, написал что-то вроде этого в C (если я много использовал strncmp и не хотел делать подсчет символов):
if(... strncmp(argv[i], "--help", sizeof("--help") - 1) == 0
Вероятно, это не сделано для безопасности. Это можно было бы сделать, чтобы проверить только начало параметра командной строки. Многие программы просто проверяют начало команд командной строки и игнорируют остальные.
er... технически не могло произойти подобное?
char *cp1 = "help";
cp1[4] = '!'; // BAD PRACTICE! don't try to mutate a string constant!
// Especially if you remove the terminating null!
...
strcmp(some_variable, "help");
// if compiler is "smart" enough to use the same memory to implement
// both instances of "help", you are screwed...
Я предполагаю, что это патологический случай и/или мусор, мусор ( "Док, мне больно, когда я ударяю головой о стену!" "Тогда не делай этого!" )...
(p.s. Я просто поднимаю вопрос - если вы чувствуете, что этот пост мутит воды, комментируйте соответствующим образом, и я удалю его)