LINUX.ORG.RU

Использование const в аргументах функции в сях


0

1

Такой вопрос: в чем принципиальная разница между

void func(int arg)
и
void func(const int arg)
? Ведь во втором случае, получается, единственное чего нельзя делать - это использовать arg в качестве изменяемой локальной переменной. Но все равно ведь можно сделать так:
void func(const int arg) {
    int arg_local = arg;
    arg_local++;
    ...
}

Была мысль, что в первом случае нельзя сделать такой вызов:

func(5)
то есть подать на вход константу. Но gcc даже warning-ов не выдает. Так все же: имеет ли какой-то смысл использование const для стандартных типов в аргументах функции при передаче по значению (т. е. без использования указателей)?

★★★

Последнее исправление: Kiborg (всего исправлений: 1)

Ответ на: комментарий от LamerOk

Для «внутреннего» кода это дело сугубо опционально

Если ты не сам для себя стартапы пишешь, то твоим «внутренним кодом» может пользоваться не один десяток человек, и они наверняка скажут тебе спасибо, если ты вместо обфускации char*'ами будешь применять const char* по месту.

А код с mktemp, который ты привел, будет сегфолтится без -fwriteable-strings.

red_eyed_peguin
()
Ответ на: комментарий от red_eyed_peguin

твоим «внутренним кодом» может пользоваться не один десяток человек,

И им всем вместо телепатии придётся смотреть инварианты каждой функции, которой они пользуются. Попсовые консты тут нисколько не помогут, зато могут создать лишний гемор через десяток итераций, особенно, когда в очередной раз изменится ТЗ. Кроме того, это работает в обе стороны: мне самому совсем не улыбается получить «подарочек» вроде вышеприведенного sqlite3Fts3NextToken.

А код с mktemp, который ты привел,

Код, который я привёл, это типичный код до выхода первого стандарта. Для компиляторов того времени любой строковый литерал - это просто инициализированный статический массив.

LamerOk ★★★★★
()
Ответ на: комментарий от red_eyed_peguin

Время-то изменилось

А код остался. Сюрприз, правда? ;) В иксорге, к примеру, эти ворнинги вычищают только сейчас - в 11/12 годах.

Следи за темой - речь шла о том, почему разрабы гцц убрали этот ворнинг в дальний задний угол.

LamerOk ★★★★★
()
Ответ на: комментарий от LamerOk

Ты идиот. Для тупых ещё раз повторяю: такой код, собранный gcc сейчас, падает. Потому что литералы нынче неизменяемы. Именно поэтому убирать это предупреждение в gcc — диверсия. Сколько ещё раз специально для криворуких тупиц это повторить?

kemm
()
Ответ на: комментарий от kemm

Диверсия, диверсия. Кругом «криворучки» и враги, начиная прямо с Ритчи и заканчивая разрабами гцц, всё хорошо, всё нормально, иди попей валерьяночки, погуляй на улице, подыши свежим воздухом...

LamerOk ★★★★★
()
Ответ на: комментарий от LamerOk

Что, наконец-то осознал, как ты ловко в лужу садился? 8))))

Криворучка — это не Ритчи (светлая ему память), он-то нормально писал, криворучка — это ты, который не знает языка и лезет оправдывать идиотское решение на основании практики использования Fortran66. Бегом учиться или вон из профессии.

kemm
()
Ответ на: комментарий от kemm

Конечно, конечно, больной. Проходите, проходите..

* Запись в медицинском журнале *

Состояние стабльное, удовлетворительное. Старые фантазии о

А over 9k криворучек стало как раз после отмены этого варнинга, до сих пор вылезают падения иногда при попытке где-нибудь унутрях libc поменять литерал, переданный туда через 15 функций, все из которых с аргументами 'char *'

исчезли, больной больше не называет «фиговым» любой код по принципу

Если функция не меняет объект — она обязана иметь аргументом 'const object_type *', и никак иначе. В противном случае это фиговый код, а не «ненекоторый хороший проект»

, а майнтенйров проектов в десятки и тысячи SLOC - «криворучками». Так же исчезла мания залитых уриной кусков ткани. Однако сохраняются негативные тенденции. У больного появилась мания на почве Fortran'а, его по-прежнему мучают мысли о профессии, учёбе и лужах.

LamerOk ★★★★★
()
Ответ на: комментарий от LamerOk

Всё-таки ты туп как пробка. Код, в котором неизменяемые аргументы не объявляются как const object *, является говнокодом. Тип строкового литерала char * при фактической его неизменяемости — диверсия (потому что это нарушение соглашения). Те, кто ныл, что этот варнинг мешает жить — криворучки (потому что руки кривые, surprise — этот варнинг только позволяет отловить говнокод (ну или не говно-, а оставшийся неизменным с 79го года, который сейчас будет падать), и пряморуким программистам не мешает). Ты — идиот, не знающий язык С (так что там с инициализацией массива и присвоением указателя, и выдуманной тобой тождественностью массива указателю? Разобрался уже? 8)) ), с фантазиями, что over 9k кода написано такими же криворукими идиотами (попытавшись тест выдать за код проекта, ага — вот только вся библиотека sqlite написана пряморукими товарищами с const char *, а не через задницу). Говорящий никнейм такой говорящий, да.

kemm
()
Ответ на: комментарий от kemm

Код, в котором неизменяемые аргументы не объявляются как const object *, является говнокодом.

У пациента снова острый приступ. ))

вот только вся библиотека sqlite написана пряморукими товарищами

Правда? Ну, ок. Вот тебе прототипы трёх функций:

static int fillInUnixFile(
  sqlite3_vfs *pVfs,      
  int h,                  
  int dirfd,              
  sqlite3_file *pId,      
  const char *zFilename,  
  int noLock,             
  int isDelete,           
  int isReadOnly          
);


static int unixOpen(
  sqlite3_vfs *pVfs,      
  const char *zPath,      
  sqlite3_file *pFile,    
  int flags,              
  int *pOutFlags          
);

static int unixFullPathname(
  sqlite3_vfs *pVfs,            
  const char *zPath,            
  int nOut,                     
  char *zOut                    
);

Твоё домашнее задание - показать, где и как изменяется объект по ссылке pVfs в теле любой из этих трёх функций.

Там таких функций не три, а сильно больше, но я боюсь, ты и эти три не осилишь...

LamerOk ★★★★★
()
Ответ на: комментарий от LamerOk

Так что там про массив и указатель? Разобрался наконец или нет?

Твоё домашнее задание

Мал ещё. Сначала язык подучи.

показать, где и как изменяется объект по ссылке pVfs в теле любой из этих трёх функций

Эти функции идут в поля структуры, описывающей методы работы с файлами на разных осях (судя по имени — мне откровенно лень ради двоечника в sqlite смотреть). Даже если вдруг сейчас для поддерживаемых ОС никому не требуется изменять состояние pVfs, то не факт, что в каком-нибудь kolibriOpen() этого не потребуется. Мне что, как в детском саде, надо было описывать каждый случай, когда не надо ставить const? То присвоение аргумента полю в структуре, то семейство функций с единой сигнатурой — не надоело клоунаду устраивать? Наиболее общий принцип — надо ставить const, но есть ряд ситуаций, когда не надо. Так легче стало или полный список нужен?

Ты б лучше про предупреждение что-нибудь ответил, а то как-то тихо слился, а я тут без лулзов мучаюсь. Так как, код 79го года с передачей литерала в mktemp(char *) сейчас при помощи gcc:

  • собирается?
  • не выдавая варнингов?
  • работает?
kemm
()
Ответ на: комментарий от kemm

Так что там про массив и указатель?

Ты на редкость тугой малый. Это был очень толстый намёк (тонкие к тому моменту уже кончились, так как ничего, кроме фортрана, в твоей безграмотной башке не вызывали), который тебе надо было погуглить самостоятельно. Если бы ты погуглил, ты бы так потом не опозорился полным незнанием K&R, и мне не пришлось бы возить тебя носом по выхолопу грепа на mktemp из исходников v7.

Наиболее общий принцип — надо ставить const, но есть ряд ситуаций, когда не надо.

Поздновато ты начал отказываться от собственных слов. ;)

судя по имени — мне откровенно лень ради двоечника в sqlite смотреть

Ну наконец-то, что ты публично признался, что ты типичный лоровский звиздабол, заменяющй реальность фантазиями по причине полной неспособности читать исходники.

Спасибо тебе, за показанную клоунаду, я думаю, нашим телезрителям она понравилась, и они сделают выводы из этой нравоучительной истории. ;)

LamerOk ★★★★★
()
Ответ на: комментарий от LamerOk

Если бы ты погуглил, ты бы так потом не опозорился полным незнанием K&R

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

и мне не пришлось бы возить тебя носом по выхолопу грепа на mktemp из исходников v7.

Напоминаю для выпускников школы для альтернативно-одарённых детей (или тебя выгнали, я что-то уже подзабыл?): речь шла об изменениях в 4ой (емнип) версии gcc. Так ты уже собрал им тестовый пример:

#include <stdio.h>
#include <stdlib.h>

int
main()
{
    char *tmpfile = mktemp("/tmp/oopsXXXXX");

    printf("%s\n", tmpfile);
    return 0;
}

Предупреждений нет даже с '-Wall -Wextra', right? И как, работает? Я ещё раз повторяю: тип 'char *' у литералов может быть только в том случае, если их таки можно менять (как было во времена v7, как было у старого gcc с -fwriteable-strings, но речь была про более новый gcc, в котором из-за нытья криворучек сделали его 'char *', оставив read-only, что является нарушением соглашений). Это не слишком сложно для тебя?

Поздновато ты начал отказываться от собственных слов. ;)

Какие-то странные у тебя фантазии. Я всё-таки расчитывал на уровень хотя бы старших классов, а не детсада, чтобы подробно расписывать — исключения довольно-таки очевидны любому, кто на С пишет, а не бредит на лоре.

Ну наконец-то, что ты публично признался, что ты типичный лоровский звиздабол, заменяющй реальность фантазиями по причине полной неспособности читать исходники

Занятные у тебя проекции, аднака.

Спасибо тебе, за показанную клоунаду, я думаю, нашим телезрителям она понравилась, и они сделают выводы из этой нравоучительной истории. ;)

От зеркала отойди всё же.

kemm
()
Ответ на: комментарий от LamerOk

Более того, в сишечке не принято даже данные по указателю защищать констом.

Хм, а разве это не будет подсказкой для всяких аналитических тулзней типа Valgrind?

Macil ★★★★★
()
Ответ на: комментарий от Macil

Ты точно имеешь в виду «типа Valgrind»? Потому что Valgrind - это тулза рантайм проверки, и она не занимается анализом исходного кода как такового. Так что вопрос, видимо, о статических анализаторах типа splint/LCLint и К°?

Нет, им это не сильно поможет. Фактически их возможности равны таковым у компилятора, да и сосредоточены они в основном на partial evaluation и value range анализах.

LamerOk ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.