Модераторы: bsa

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Применяется const в параметрах функции? 
:(
    Опции темы
hoz
Дата 3.9.2014, 19:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 139
Регистрация: 27.6.2013

Репутация: нет
Всего: нет



 Я призадумался сегодня. Вот ведь есть модификатор const. В самих функциях и классах он применяется. А вот в параметрах функции применяется или нет? Я заметил, что не часто.
 Хотя по сути,  если параметр функции не изменяется, то можно было бы и применить. Так?
 Или это не обязательно?
PM MAIL   Вверх
baldman88
Дата 4.9.2014, 07:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 210
Регистрация: 18.1.2009

Репутация: 1
Всего: 7



Цитата(hoz @  3.9.2014,  19:14 Найти цитируемый пост)
Я заметил, что не часто.

Почему же это. Посмотрите исходники хороших open source проектов. Применение const в параметрах помогает избежать трудновылавливаемых ошибок.
Хотя есть люди, которые имеют совершенно противоположное мнение и считают, что применение const в параметрах это зло.
PM MAIL   Вверх
math64
Дата 4.9.2014, 08:22 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2505
Регистрация: 12.4.2007

Репутация: 12
Всего: 72



Цитата(baldman88 @  4.9.2014,  07:51 Найти цитируемый пост)
Хотя есть люди, которые имеют совершенно противоположное мнение и считают, что применение const в параметрах это зло. 

Просто у них есть много кода, в котором const не применяется.
Если им посоветешь применять const, они обнаруживают, что придётся вносить изменения во все старые исходники, и поэтому отказываюся от его использования.

Это сообщение отредактировал(а) math64 - 4.9.2014, 08:23
PM   Вверх
borisbn
Дата 4.9.2014, 12:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 4875
Регистрация: 6.2.2010
Где: Ростов-на-Дону

Репутация: 21
Всего: 135



Цитата(hoz @  3.9.2014,  19:14 Найти цитируемый пост)
Я заметил, что не часто.

Наоборот. Применяется. И повсеместно. Если в каких-то исходниках можно добавить const, но его там нет, то это - плохие (или очень старые, как заметил math64).
Ещё один момент - в языке Си (не путать с Си++) до стандарта С99 модификатора const просто не было, А огромное количество исходников написано именно на нём. Они прекрасно (ну... почти) компилируются современными компиляторами Си++, и их просто никто не хочет модифицировать. Работает - и ладно.

Это сообщение отредактировал(а) borisbn - 4.9.2014, 12:56


--------------------
Женщины отличаются от программистов тем, что у них чары состоят из стрингов
PM MAIL Jabber   Вверх
kemiisto
Дата 4.9.2014, 14:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Дикий Кот. =^.^=
****
Награды: 1



Профиль
Группа: Участник Клуба
Сообщений: 3292
Регистрация: 29.7.2007

Репутация: 5
Всего: 160



Цитата(borisbn @  4.9.2014,  11:55 Найти цитируемый пост)
А огромное количество исходников написано именно на нём

А ещё немалое количество исходников написано на адской смеси C/C++, в которой вообще что угодно можно увидеть. По сабжу же, конечно, достаточно будет процитировать владыку нашего Мейерса smile 
Цитата
Правило 3: Везде, где только можно, используйте const

и отослать ТСа за подробностамя к фолианту Мейерс - Эффективное использование C++, 3-е изд. (2006). smile 


--------------------
PM MAIL WWW GTalk Jabber   Вверх
hoz
Дата 6.9.2014, 14:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 139
Регистрация: 27.6.2013

Репутация: нет
Всего: нет



Цитата(baldman88 @  4.9.2014,  07:51 Найти цитируемый пост)
Почему же это. Посмотрите исходники хороших open source проектов

Где бы их увидеть...

Я чего спросил. Вот, например, у меня метод:
Код

int      fOrderSend (string fs_Symbol, int fi_Type, double fd_Lot, double fd_Price, int fi_Slip, double fd_SL, double fd_TP,
                           int fi_Magic = 0, string fs_Comm = "", datetime fdt_Expiration = 0, color fc_Arrow = CLR_NONE);


Получается правильно его сделать так выходит, судя по вышенаписанному.. :
Код

int      fOrderSend (const string fs_Symbol, const  int fi_Type, const  double fd_Lot, const  double fd_Price, const int fi_Slip, double fd_SL, double fd_TP,
                           iconst  nt fi_Magic = 0, const  string fs_Comm = "", const  datetime fdt_Expiration = 0, const  color fc_Arrow = CLR_NONE);

Верно? Получается, что методы "удлинняются"
PM MAIL   Вверх
borisbn
Дата 6.9.2014, 18:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 4875
Регистрация: 6.2.2010
Где: Ростов-на-Дону

Репутация: 21
Всего: 135



11 параметров в функции - уже плохо. А вообще - принято простые типы (int, double, etc.) передавать по значению, а объекты (string, datetime, etc.) - по константной ссылке. Т.о. твой метод д.б. таким
Код
int      fOrderSend (const string & fs_Symbol, int fi_Type, double fd_Lot, double fd_Price, int fi_Slip, double fd_SL, double fd_TP,
                           int fi_Magic = 0, const  string & fs_Comm = "", const  datetime & fdt_Expiration = 0, const color & fc_Arrow = CLR_NONE);

Цитата(hoz @  6.9.2014,  14:53 Найти цитируемый пост)
Получается, что методы "удлинняются" 

и ?
Код пишется один раз, а читается - много.
Цитата(hoz @  6.9.2014,  14:53 Найти цитируемый пост)
Где бы их увидеть...

github, sourceforge


--------------------
Женщины отличаются от программистов тем, что у них чары состоят из стрингов
PM MAIL Jabber   Вверх
baldina
Дата 6.9.2014, 20:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3433
Регистрация: 5.12.2007
Где: Москва

Репутация: 15
Всего: 101



Цитата(hoz @  6.9.2014,  14:53 Найти цитируемый пост)
Получается правильно его сделать так выходит, судя по вышенаписанному

нет. параметры передаются по значению, поэтому ставить перед ними const - тавтология. так что в упомянутой функции fOrderSend const вообще не нужен.
const имеет смысл, только если параметр передается по ссылке или указателю, что бы избежать лишнего копирования. обычно это делается для сложных типов (которые длиннее указателя).  тогда функция превращается в то, что показал borisbn.
PM MAIL   Вверх
hoz
Дата 6.9.2014, 23:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 139
Регистрация: 27.6.2013

Репутация: нет
Всего: нет



Цитата(baldina @  6.9.2014,  20:54 Найти цитируемый пост)
нет. параметры передаются по значению, поэтому ставить перед ними const - тавтология. так что в упомянутой функции fOrderSend const вообще не нужен.

Согласен. Я это и хотел отписать. Какой резон писать const перед переменной, которая передаётся по ссылке и модифицируется, а после возвращается по ссылке из функции в вызывающую.
PM MAIL   Вверх
sQu1rr
Дата 8.9.2014, 00:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 597
Регистрация: 11.11.2008
Где: london

Репутация: 3
Всего: 13



Цитата(hoz @  6.9.2014,  23:50 Найти цитируемый пост)
Какой резон писать const перед переменной, которая передаётся по ссылке и модифицируется, а после возвращается по ссылке из функции в вызывающую. 

щито?  smile 
PM MAIL Skype GTalk   Вверх
borisbn
Дата 8.9.2014, 00:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 4875
Регистрация: 6.2.2010
Где: Ростов-на-Дону

Репутация: 21
Всего: 135



Полностью согласен с предыдущим оратором. Ни разу не понял этой фразы


--------------------
Женщины отличаются от программистов тем, что у них чары состоят из стрингов
PM MAIL Jabber   Вверх
Lukkoye
Дата 8.9.2014, 11:44 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 86
Регистрация: 23.3.2013

Репутация: нет
Всего: 1



Цитата(baldina @  6.9.2014,  20:54 Найти цитируемый пост)
нет. параметры передаются по значению, поэтому ставить перед ними const - тавтология.


Вы ошибаетесь.

Квалификатор const гарантирует, что имя будет использовано только для чтения.

Это важно не только для читабельности, и оптимизации (древним компиляторам помогало оптимизировать код), но так же является важным требованием для строгих гарантий.

Строгая гарантия - гарантия, что в случае, если процедура зафейлится, данные не будут утеряны:

Код

void foo( const int val  )
{
     val = calculate(data);  //нельзя! Строгая гарантия - исходные данные не будут повреждены в случае провалов

     ...

     //здесь полетели исключения, и отработало восстановление после паники - откат транкзации
}



Если же вы не указываете const у аргумента, значит теоретически вы можете перетереть входной аргумент.

Читатель уже не может закладываться на строгие гарантии кода.
В момент Х нельзя знать наверняка, содержит ли входной аргумент оригинальное значение, или его уже перетерли.


В книжках рекомендуют использовать const по максимуму: везде, где только возможно.

Я бы дополнил эту рекомендацию - если без особых затрат, вы можете предоставить строгие гарантии - сделайте это. 


От того что вы напишите лишний раз const для аргумента, который является значением - не переломаетесь.

Однако, профит от такой практики налицо: строгие гарантии безопасности, лучше оптимизация, выше читабельность кода.



Это сообщение отредактировал(а) Lukkoye - 8.9.2014, 11:47
PM MAIL   Вверх
baldina
Дата 8.9.2014, 13:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3433
Регистрация: 5.12.2007
Где: Москва

Репутация: 15
Всего: 101



Цитата(Lukkoye @  8.9.2014,  11:44 Найти цитируемый пост)
Если же вы не указываете const у аргумента, значит теоретически вы можете перетереть входной аргумент.

и практически тоже:
Код

int foo (int i) {
  int sum=0;
  for (; i != 0; --i)
    sum += i;
  return sum;
}

однако это не касается переменной в вызове, т.к. передается не она сама, а копия, и с точки зрения вызывающего разницы нет.

Это сообщение отредактировал(а) baldina - 8.9.2014, 13:13
PM MAIL   Вверх
Lukkoye
Дата 8.9.2014, 13:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 86
Регистрация: 23.3.2013

Репутация: нет
Всего: 1



Цитата(baldina @  8.9.2014,  13:11 Найти цитируемый пост)
однако это не касается переменной в вызове, т.к. передается не она сама, а копия, и с точки зрения вызывающего разницы нет.


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

Однако, вызывающая сторона стороне рознь.

Код

int foo (int i) {

    try{
        int sum=0;
        for (; i != 0; --i) //<---- перетираем исходные данные
            Sum(sum,i); //<---- может кинуть исключение
        return sum;
    }
    catch(...)
    {
        //причин для волнений нет, у нас предусмотрена штатная обработка всех возможных проблем
        //просто откатываем весь цикл назад, и восстановливаемся после паники
        ...
             
        //перезапуск функции
        foo(i); //<---- upsss, исходные данные уже безвозвратно запорчены
    }
}


Формально Sum дает строгие гарантии, потому что всегда работает с копией аргумента. 
В случае аварии мы всегда знаем каким было последнее валидное i, с которой операция прошла успешно.

Однако Sum здесь - лишь часть большого цикла. Лишь один из элементов большой транкзации.
В случае провала функции foo, откатить нужно весь цикл, а не только последнюю неудавшуюся итерацию.

Но это не возможно, просто потому, что кому то было лень обезопасить исходные данные:

Код

int foo (const int index) {
    try{
        int sum=0;
        for (int i = index; i != 0; --i)
            Sum(sum,i); 
        return sum;
    }
    catch(...)
    {
        //восстанавливаемся
        ...

        //перезапускаемся      
        foo(index); 
    }
}



Добавлено @ 13:44
Если в каком то частном случае строгие гарантии не нужны, а их обеспечение сопряжено с неоправданными усилиями - тогда конечно не стоит так заморачиваться, и лучше делать так, как проще и удобнее.

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

Поэтому, лично я решил согласиться с рекомендациями и вписываю const по максимуму везде, где только можно, тем паче, обычно это не сопряжено с какими то дополнительными усилиями, и не отнимает время.




Это сообщение отредактировал(а) Lukkoye - 8.9.2014, 13:45
PM MAIL   Вверх
feodorv
Дата 9.9.2014, 06:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2214
Регистрация: 30.7.2011

Репутация: 12
Всего: 45



Эх, const это ещё цветочки. Microsoft учудила сначала это, потом это. Вот это да...


--------------------
Напильник, велосипед, грабли и костыли - основные инструменты программиста...
PM MAIL   Вверх
baldina
Дата 9.9.2014, 10:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3433
Регистрация: 5.12.2007
Где: Москва

Репутация: 15
Всего: 101



Lukkoye, ход вашей мысли понятен и возражений по сути ситуаций, выстреливающих в ногу, не вызывает. но пример ваш аналогичен
Код

void foo () {
  int x=...;
  try {
     while (x)
       bar(--x);
  } catch (...) {
     baz(x);
  }
}
vs
void foo () {
  const int x=...;
  try {
     int y=x;
     while (y)
       bar(--y);
  } catch (...) {
     baz(x);
  }
}

и имхо к константности аргумента функции не относится.
что касается const вообще - да, чем меньше переменных, тем меньше ошибок.


Это сообщение отредактировал(а) baldina - 9.9.2014, 10:30
PM MAIL   Вверх
Lukkoye
Дата 9.9.2014, 11:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 86
Регистрация: 23.3.2013

Репутация: нет
Всего: 1



Цитата(baldina @  9.9.2014,  10:29 Найти цитируемый пост)
и имхо к константности аргумента функции не относится.


Относится. Его использование обусловлено причинами, по которым квалификатор const вообще ввели в язык.
А его ввели не для машины - для человека.

Задача квалификатора не просто улучшать читабельность лучше передавая намерения автора кода.
Его главная задача - предостеречь от ничайных ошибок.

Так например, передав аргумент по значению, как константный, вы получаете 100% гарантию от компилятора, что никто ничайно не перетрет его.

Вы конечно можете дать себе торжественную клятву, что никогда не будете перетирать аргумент. И там где надо - обязательно сделаете дополнительную копию.
Но это - человеческий фактор. Только компилятор может дать вам 100% гарантии.
PM MAIL   Вверх
baldina
Дата 9.9.2014, 15:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3433
Регистрация: 5.12.2007
Где: Москва

Репутация: 15
Всего: 101



Цитата(Lukkoye @  9.9.2014,  11:48 Найти цитируемый пост)
Так например, передав аргумент по значению, как константный, вы получаете 100% гарантию от компилятора, что никто ничайно не перетрет его.

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

Цитата(Lukkoye @  9.9.2014,  11:48 Найти цитируемый пост)
А его ввели не для машины - для человека.

читабельность интерфейса важнее читабельности реализации. или нет? хорошо ли интерфейсу отражать реализацию? нужно ли пользователю интерфейса знать о деталях реализации, например, что реализация не будет использовать аргумент как изменяемую переменную? не нарушается ли при этом принцип инверсии зависимостей?
PM MAIL   Вверх
baldina
Дата 9.9.2014, 16:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3433
Регистрация: 5.12.2007
Где: Москва

Репутация: 15
Всего: 101



что бы удовлетворить все стороны, не используем const в прототипе, но используем в реализации http://ideone.com/KKjcJa


Это сообщение отредактировал(а) baldina - 9.9.2014, 16:52
PM MAIL   Вверх
Lukkoye
Дата 9.9.2014, 20:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 86
Регистрация: 23.3.2013

Репутация: нет
Всего: 1



Цитата(baldina @  9.9.2014,  16:52 Найти цитируемый пост)
что бы удовлетворить все стороны, не используем const в прототипе, но используем в реализации http://ideone.com/KKjcJa


Прототип вводит в заблуждение.




PM MAIL   Вверх
sQu1rr
Дата 9.9.2014, 21:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 597
Регистрация: 11.11.2008
Где: london

Репутация: 3
Всего: 13



Цитата(Lukkoye @  9.9.2014,  20:39 Найти цитируемый пост)
Прототип вводит в заблуждение.


Цитата(baldina @  9.9.2014,  15:54 Найти цитируемый пост)
вызывающей стороне на это наплевать, т.к. она от этого никак не зависит. поэтому, кстати, вопрос и не относится к гарантиям интерфейса


Тот кто мейнтейнит реализацию и так знает что это конст, ведь в той частт кода что он правит видно что это конст
Тот кто вызывает функцию, и так понимает что если это не ссылка и не указатель то его значение не затрется. А что там делается в функции это не его дело вообще
PM MAIL Skype GTalk   Вверх
Lukkoye
Дата 9.9.2014, 22:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 86
Регистрация: 23.3.2013

Репутация: нет
Всего: 1



Цитата(sQu1rr @  9.9.2014,  21:47 Найти цитируемый пост)
А что там делается в функции это не его дело вообще 


Не дает индульгенцию на _г_о_в_н_о_код.

Код пишится один раз. И много-много раз читается.


К тому же так писать банально не удобно.
Удобно написать прототип, а потом скопипастить его для реализации, и не тратить время на коверканье нормального кода превращая его в УГ.


Это сообщение отредактировал(а) Lukkoye - 9.9.2014, 22:55
PM MAIL   Вверх
kemiisto
Дата 9.9.2014, 23:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Дикий Кот. =^.^=
****
Награды: 1



Профиль
Группа: Участник Клуба
Сообщений: 3292
Регистрация: 29.7.2007

Репутация: 5
Всего: 160



Цитата(Lukkoye @  9.9.2014,  19:39 Найти цитируемый пост)
Прототип вводит в заблуждение.

Нет, не так. Если в заблужление что и вводит, то определение, а не объявление функции. smile 

Вот, посмотрите на объявление функции:
Код
int foo (int x);

Передаём же по значению, так? Значит, фактический параметр скопируется в формальный при передаче. И, как следствие, фактический параметр измениться не может. Потому что по значению передаём, а не по ссылке.
Никаких заблуждений же! Всё так и будет независимо от наличия const в последующем определении функции.

А вот когда посмотрим на то, как функция реализована, увидим там const
Код
int foo (const int x) { ... }

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

Что даёт неизменность формального параметра? Ну, анализировать функцию вроде как проще, так как на такие параметры можно почти не обращать внимания. Но я сомневаюсь в полезности. Всё-таки постоянство формального параметра - детали реализации и выносить их в интерфейс (то есть уже в объявлении писать const) не стоит. И уж, конечно, не стоит иметь разногласия между интерфейсом и реализацией (как в примере у baldina).

Мейрса уже цитировал, надо бы и Саттера что-ли.  smile 
Цитата
Normally const pass-by-value is unuseful and misleading at best.

В вольном переводе
Цитата
Обычно передача параметров по константному значению бесполезна и в лучшем случае вводит в заблуждение.


Это сообщение отредактировал(а) kemiisto - 9.9.2014, 23:22


--------------------
PM MAIL WWW GTalk Jabber   Вверх
Lukkoye
Дата 10.9.2014, 00:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 86
Регистрация: 23.3.2013

Репутация: нет
Всего: 1



Цитата(kemiisto @  9.9.2014,  23:19 Найти цитируемый пост)
 Если в заблужление что и вводит, то определение, а не объявление функции


Не принципиально.


Цитата(kemiisto @  9.9.2014,  23:19 Найти цитируемый пост)
Передаём же по значению, так? Значит, фактический параметр скопируется в формальный при передаче. И, как следствие, фактический параметр измениться не может.


Измениться может переданный аргумент.

Мне как то не хочется по второму кругу начинать тоже самое. Читайте предысторию сообщениями раннее.

К тому же:
Код

int foo (int x);


Прототип замалчивает свои намерения: то ли он собирается перетирать аргумент. Толи писал г_о_в_н_о_кодер.

Некоторые ссылки передают изменяемые. Хотя и без намерения их изменять. Такие обычно однозначно производят впечатление джамшутов.

С аргументами-по-значению не так критично, но аналогия та же самая.

Добавлено @ 00:46
Цитата(kemiisto @  9.9.2014,  23:19 Найти цитируемый пост)
В вольном переводе


О пользе я уже написал.

Насчет заблуждений - любопытно узнать, какие тут могут быть заблуждения?

Вы видите прототип:

Код

void foo(const arg); 


А теперь расскажите мне, какие заблуждения у вас могут возникнуть при чтении этого кода?

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

Добавлено через 9 минут и 48 секунд
Цитата(kemiisto @  9.9.2014,  23:19 Найти цитируемый пост)
и узнаем, вроде как сверх того что уже знаем, что и формальный параметер тоже измениться не может.


Что такое "формальный параметр" ?

Это сообщение отредактировал(а) Lukkoye - 10.9.2014, 00:51
PM MAIL   Вверх
sQu1rr
Дата 10.9.2014, 00:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 597
Регистрация: 11.11.2008
Где: london

Репутация: 3
Всего: 13



Цитата(Lukkoye @  10.9.2014,  00:42 Найти цитируемый пост)
Прототип замалчивает свои намерения: то ли он собирается перетирать аргумент. Толи писал г_о_в_н_о_кодер.

Так смысл в том что вызывающей стороне все равно что случится с аргументом внутри функции, а вообще, что я объясняю

Цитата(Lukkoye @  10.9.2014,  00:42 Найти цитируемый пост)
Мне как то не хочется по второму кругу начинать тоже самое. Читайте предысторию сообщениями раннее.

Мне кажется это вас в большей степени касается.
PM MAIL Skype GTalk   Вверх
Guinness
Дата 10.9.2014, 07:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 310
Регистрация: 21.6.2009
Где: Зеленоград

Репутация: 2
Всего: 10



Цитата(Lukkoye @  10.9.2014,  01:42 Найти цитируемый пост)
Насчет заблуждений - любопытно узнать, какие тут могут быть заблуждения?
Вы видите прототип:
Код

void foo(const arg); 

А теперь расскажите мне, какие заблуждения у вас могут возникнуть при чтении этого кода?

Автор, скорее всего, забыл указать, что это константная ссылка, значит функция работает некорректно. Вообще, такие вещи определяются стандартам кодирования на предприятии, если у всех программистов общепринято так писать, то, наверное, данный код будет восприниматься адекватно. Хотя, как по мне, в данном случае, клиенту, пользующимся данным интерфейсом, глубоко по барабану, изменяется ли входной параметр внутри функции или нет, т.к. переданная им переменная для него не изменится.
Цитата(Lukkoye @  10.9.2014,  01:42 Найти цитируемый пост)
Саттер  (это ведь он, если не ошибаюсь, писал, что не осилил смысла протектед-наследования? ) меня разочаровывает.

Он осилил, просто сказал, что данная "фича" языка весьма сомнительна. Будем откровенны, ни разу в жизни данный вид наследования мне не пригодился, более того, я не знаю где бы его применить.

PM MAIL   Вверх
kemiisto
Дата 10.9.2014, 09:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Дикий Кот. =^.^=
****
Награды: 1



Профиль
Группа: Участник Клуба
Сообщений: 3292
Регистрация: 29.7.2007

Репутация: 5
Всего: 160



Цитата(Lukkoye @  9.9.2014,  23:42 Найти цитируемый пост)
Прототип замалчивает свои намерения: то ли он собирается перетирать аргумент. Толи писал г_о_в_н_о_кодер.

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

Цитата(Lukkoye @  9.9.2014,  23:42 Найти цитируемый пост)
Что такое "формальный параметр" ?

И этот юзернейм критикует Саттера?! smile В объявлении функции фигурируют формальные параметры, а передаются в неё в клиентском коде фактические. То есть, в объявлении, скажем,
Код
int foo(int x);

x - формальный параметр, а при вызове такой функции
Код
int a = 0;
int result = foo(a);(

a - фактический параметр.

И ещё раз, уже на этом конкретном примере: значение фактического параметра a, передающегося по значению, поменяться ну никак не может, так как при вызове функции оно будет скопировано в формальный параметр x. Значение формального параметра x при этом может измениться, но на вызывающей стороне это никак не скажеться. Ничего Вы там не перетрёте, не болтайте ерундой.

Добавлено через 1 минуту и 3 секунды
Цитата(Guinness @  10.9.2014,  06:43 Найти цитируемый пост)
Хотя, как по мне, в данном случае, клиенту, пользующимся данным интерфейсом, глубоко по барабану, изменяется ли входной параметр внутри функции или нет, т.к. переданная им переменная для него не изменится.

Ему уже как-бы 2 страницы пытаются это объяснить. 


--------------------
PM MAIL WWW GTalk Jabber   Вверх
math64
Дата 10.9.2014, 10:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2505
Регистрация: 12.4.2007

Репутация: 12
Всего: 72



const в java соответсвует final.
Если параметр объявлен final, анонимный класс, создаваемый в методе, имеет к нему доступ:
Код

public class C {
public getX() { return x; }
private int x = 0;
}
int foo(final int x) {
   C c = new C() { public int getX() { return x; } }
   return c.getX();
}

T.o. лишние final могут быть вредны с точки зрения обнаружения ошибок в коде.
Вероятно подобные примеры можно найти в C++ (с учётом наличия лямбда выражений, шаблонов и т.п.)
PM   Вверх
kemiisto
Дата 10.9.2014, 10:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Дикий Кот. =^.^=
****
Награды: 1



Профиль
Группа: Участник Клуба
Сообщений: 3292
Регистрация: 29.7.2007

Репутация: 5
Всего: 160



Цитата(math64 @  10.9.2014,  09:17 Найти цитируемый пост)
const в java соответсвует final

Ничего подобного. Там столько различий, что надоест перечислять. Тут с одним С++ то разобраться не можем. smile 

Это сообщение отредактировал(а) kemiisto - 10.9.2014, 10:38


--------------------
PM MAIL WWW GTalk Jabber   Вверх
Lukkoye
Дата 10.9.2014, 18:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 86
Регистрация: 23.3.2013

Репутация: нет
Всего: 1



Цитата(kemiisto @  10.9.2014,  09:41 Найти цитируемый пост)
Lukkoye, у меня для Вас плохие новости: Вы не понимаете механизма передачи параметра функции по значению. Ещё раз для Вас повторю: при передаче по значению фактический параметр копируется в формальный, и далее, какие-бы изменения с формальным параметром не произошли, на фактическом параметре они никак не отразяться.


У меня тоже для вас плохие новости - вы невнимательный. Вы не читали предысторию.

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

Цитата(kemiisto @  10.9.2014,  09:41 Найти цитируемый пост)
 объявлении функции фигурируют формальные параметры, а передаются в неё в клиентском коде фактические. То есть, в объявлении, скажем,


Ясно. Спасибо.

Возвращаясь к вашей цитате:
Цитата(kemiisto @  9.9.2014,  23:19 Найти цитируемый пост)
и узнаем, вроде как сверх того что уже знаем, что и формальный параметер тоже измениться не может.


Эта полезная информация. Мы можем не вникать в детали без необходимости, но мы знаем, и нам это гарантирует компилятор - формальный параметр ни при каких обстоятельствах не будет перетерт.
А это значит, что функция дает нам строгие гарантии.

Гарантии, который предоставляет компилятор помогают не только человеку, который непосредственно пишет реализацию функции. 
Но и его коллегам - потом читать этот код и поддерживать код.
Просто потому, что лучше отображает намерения.

Цитата(kemiisto @  10.9.2014,  09:41 Найти цитируемый пост)
Ему уже как-бы 2 страницы пытаются это объяснить.  


Это если только в стране фей.

На практике же, как дойдет дело то кодовой базы, которую пилит куча народу - чем более самодокументируемый и безопасный код - тем лучше во всех смыслах.





Это сообщение отредактировал(а) Lukkoye - 10.9.2014, 18:15
PM MAIL   Вверх
kemiisto
Дата 10.9.2014, 19:21 (ссылка) |    (голосов:2) Загрузка ... Загрузка ... Быстрая цитата Цитата


Дикий Кот. =^.^=
****
Награды: 1



Профиль
Группа: Участник Клуба
Сообщений: 3292
Регистрация: 29.7.2007

Репутация: 5
Всего: 160



Lukkoye, ну, давайте попробуем разложить всё по полочкам. Итак, вот ключевая цитата из Вашего первого(?) сообщения в этой теме.
Цитата(Lukkoye @  8.9.2014,  10:44 Найти цитируемый пост)
Это важно не только для читабельности, и оптимизации (древним компиляторам помогало оптимизировать код), но так же является важным требованием для строгих гарантий.

За оптимизации в древних компиляторах ничего не скажу, но остальное - не верно. И вот почему.

Полочка №1

Объявление функции - часть интерфейса, а её определение - детали реализации. Клиенты обладают информацией только об интерфейсе, и ничего сверх того, что специфицирует и гарантирует интерфейс, им не известно и не должно быть известно.

Полочка №2

Крайне желательно чтобы интерфейс и реализация соответствовали друг другу. В случае функции это означает, что список формальных параметров в объявление функции и её определени должны совпадать. Вплоть до квалификаторов. Поэтому вариант, где в объявлении нет квалификатора const, а в определении есть, отметаем сразу.

Полочка №3

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

Код
int foo(const int x);
int foo(const int x) { ... };


Код
int foo(int x);
int foo(int x) { ... };


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

Код
int foo(const int x);


Код
int foo(int x);


Даёт ли первый вариант какие-либо дополнительные гарантии? Нет, никаких. Фактический параметр в обоих вариантах передаётся по значению, а значит будет скопирован при передаче и изменений в ходе выполнения функции не притерпит. Единтсвенное, что помимо этого сообщает функция в первом варианте, так это то, что и формальный параметр в ходе её выполнения изменений тоже не притерпит. НО! Это деталь реализации, которая клиентскому коду вообще знать незачем. 

Цитата(Lukkoye @  9.9.2014,  23:42 Найти цитируемый пост)
Прототип замалчивает свои намерения: то ли он собирается перетирать аргумент. Толи писал г_о_в_н_о_кодер.

Ещё раз повторю, Вы ошибаетесь. Прототип своих намерений не замалчивает. Фактический аргумент передаётся по значению, и во время выполнения функции его значение не измениться.

Это сообщение отредактировал(а) kemiisto - 10.9.2014, 19:21


--------------------
PM MAIL WWW GTalk Jabber   Вверх
Lukkoye
Дата 10.9.2014, 20:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 86
Регистрация: 23.3.2013

Репутация: нет
Всего: 1



Цитата(kemiisto @  10.9.2014,  19:21 Найти цитируемый пост)
Объявление функции - часть интерфейса, а её определение - детали реализации. Клиенты обладают информацией только об интерфейсе, и ничего сверх того, что специфицирует и гарантирует интерфейс, им не известно и не должно быть известно.


Ещё раз повторяю - только в стране сказочных фей.

Меня не очень интересует "точка зрения только клиента". 

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

Однако, ваш собственный проект - многоярусный, многоэтажный, многослойный, который помимо вас пилит целая команда - там одной лишь инкапсуляции недостаточно.
Так или иначе, но вам придется заглядывать и на более нижние, и на более верхние этажи.

Меня интересует точка зрения разработчика, которому нужно поддерживать сложный командный проект на протяжении времени.

Поэтому я заинтересован в том, что бы иметь максимум гарантий от компилятора. 
И в том, что бы код был самодокументированный - хорошо передавал намерения своего автора.

Добавлено @ 20:18
Цитата(kemiisto @  10.9.2014,  19:21 Найти цитируемый пост)
Прототип своих намерений не замалчивает. 


Я хочу что бы вы прочитали текст. И сказали мне, какие мысли вкладывал программист в эти строки:

Код

voo foo(const some& obj);

voo bar(const some* obj);

voo baz(int index);


Я приведу вам пример:

функция baz:
Что делает - очно не ясно. Но судя по наименованию (foo/bar/baz/etc) - просто маленький демонстрационный пример.
Если автор не г_о_в_н_о_кодер, значит индекс с которым она работает - реально может быть отрицательным числом. 
Функция может перетереть свой формальный параметр, а значит не дает никаких строгих гарантий.

Теперь ваша очередь. 
Вам нужно просто рассказать о том, что по вашему хотел сделать программист.

Это сообщение отредактировал(а) Lukkoye - 10.9.2014, 20:20
PM MAIL   Вверх
sQu1rr
Дата 10.9.2014, 21:09 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 597
Регистрация: 11.11.2008
Где: london

Репутация: 3
Всего: 13



Цитата(Lukkoye @  10.9.2014,  20:12 Найти цитируемый пост)
Теперь ваша очередь. 
Вам нужно просто рассказать о том, что по вашему хотел сделать программист.

Программист хотел доказать свою точку зрения 3мя демонстраивными функциями, не понимая, что спор о совершенно разных вещях. Его породило ваше высказывание:
Цитата(Lukkoye @  10.9.2014,  20:12 Найти цитируемый пост)
Это действительно не касается вызывающей стороны, несчитая того, 
что теряется информация о том, будет ли вызываемая сторона перетирать данные, или же использовать их только для чтения.

после которого уже 2 страницы идет обсуждение того, что эта точка зрения не верна (вы же сами указали "со стороны клиента").

Стоило вам написать что то вроде "мне нравится использовать конст как программисто, и считаю, что это делает поддержку большого проекта более понятным и само-документируемым хоть и нарушает принцыпы инкапсуляции, ИМХО" и ничего такого бы небыло.
PM MAIL Skype GTalk   Вверх
kemiisto
Дата 10.9.2014, 21:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Дикий Кот. =^.^=
****
Награды: 1



Профиль
Группа: Участник Клуба
Сообщений: 3292
Регистрация: 29.7.2007

Репутация: 5
Всего: 160



Цитата(Lukkoye @  10.9.2014,  19:12 Найти цитируемый пост)
Теперь ваша очередь. 

За ссылки и указатели говорить не буду, так как речь не о них. Речь только о передаче по константному значению.

И гляда на функцию baz, объявленную следующим образом,
Код
voo baz(int index);

я могу заключить, что при вызове такой функции в моём клиентском коде как-нибудь так
Код
voo v = baz(i);

фактический параметр i передаcтся по значению, т.е. значение фактического параметра i будет скопировано в значение формального параметра index. Это гарантирует мне, что значение фактического параметра i во время вызова baz() не изменится. И если мне эта гарантия по какой-то причине важна, то у меня в голове сразу складывается следующая картина {предусловие} команда {постусловие}:
Код
{i = a} baz(i) {i = a}

Значение i до и после вызова baz(i) одинаковы, или, иными словами, i является инвариантом данной функции.

Цитата(Lukkoye @  10.9.2014,  19:12 Найти цитируемый пост)
Функция может перетереть свой формальный параметр, а значит не дает никаких строгих гарантий.

Да какого, простите, Вам вообще дела до формального параметра? Каких-таких гарантий мне не даёт функция без index, объявленного как const? Что с const, что без него строго гарантированно
Код
{i = a} baz(i) {i = a}

И баста!

Конечно, на уровне реализации const даёт нам инвариантность формального параметра внутри самой функции
Код
voo baz(const int index)
{
    {index = a} ... {index = a}
}

В принципе я могу понять, зачем это нужно. НО! В интерфейсе const для pass-by-value параметров бессмысленен, так как никаких дополнительных гарантий на уровне интерфейса не даёт. Остаётся только вариант, где в интерфейсе квалификатор const опущен, а в реализации он в наличии, если уж Вам так нужно гарантировать неизменность формального параметра. Но мне такой вариант не нравится из-за несоответствия объявления функции её определению (Полочка №2 из предыдущего сообщения).

Это сообщение отредактировал(а) kemiisto - 10.9.2014, 21:21


--------------------
PM MAIL WWW GTalk Jabber   Вверх
sQu1rr
Дата 10.9.2014, 21:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 597
Регистрация: 11.11.2008
Где: london

Репутация: 3
Всего: 13



Цитата(kemiisto @  10.9.2014,  19:21 Найти цитируемый пост)
Крайне желательно чтобы интерфейс и реализация соответствовали друг другу.

Не всегда возможно, потому что не нужно
Код

int x(int y = 3);
int x(int y) { ... } // нельзя 2 раза" y = 3"

почему же тогда и const не использовать лишь в одном месте? smile

Это сообщение отредактировал(а) sQu1rr - 10.9.2014, 21:50
PM MAIL Skype GTalk   Вверх
Lukkoye
Дата 10.9.2014, 23:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 86
Регистрация: 23.3.2013

Репутация: нет
Всего: 1



Цитата(sQu1rr @  10.9.2014,  21:09 Найти цитируемый пост)
хоть и нарушает принцыпы инкапсуляции


Дану? Интересно, каким же образом?


Цитата(kemiisto @  10.9.2014,  21:19 Найти цитируемый пост)
За ссылки и указатели говорить не буду, так как речь не о них.


Значит эксперимент не состоялся.

Цитата(kemiisto @  10.9.2014,  21:19 Найти цитируемый пост)
Да какого, простите, Вам вообще дела до формального параметра?


Вы не внимательны.
Я уже писал выше - сопровождение кода.

Это значит не только использовать - но и дорабатывать. В том числе за другими. В том числе другие будут дорабатывать после меня.

Самодокументируемость + гарантии от компилятора, что никто ничайно не напортачит.

 
PM MAIL   Вверх
math64
Дата 11.9.2014, 08:04 (ссылка) |    (голосов:2) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2505
Регистрация: 12.4.2007

Репутация: 12
Всего: 72



Цитата(Lukkoye @  10.9.2014,  23:10 Найти цитируемый пост)
Цитата(kemiisto @  10.9.2014,  21:19 Найти цитируемый пост)
За ссылки и указатели говорить не буду, так как речь не о них.


Значит эксперимент не состоялся.

Раз Вы настаиваете на использовании const, то должны требовоать const и с указателями:
Код

voo bar(const some* const obj);
voo baz(const int index);

Такое компилятор вроде тоже сожрёт (не проверял), хотя смысла особого нет:
Код

voo foo(const some& const obj);

А вообще Ваш спор бессмысленен,  аргументы строн понятны, разве что кто-то найдёт пример вредности такого использования const в С++.

Это сообщение отредактировал(а) math64 - 11.9.2014, 08:24
PM   Вверх
math64
Дата 11.9.2014, 10:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2505
Регистрация: 12.4.2007

Репутация: 12
Всего: 72



Предлагаю компромисс: использовать const только для параметров, имеющих значения по умолчанию.
Был код:
Код

void func() {
   const int count = 10;
   ...
}

Потребовалась возможность менять count:
Код

void func(const int count = 10) {
   ...
}

PM   Вверх
Lukkoye
Дата 12.9.2014, 17:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 86
Регистрация: 23.3.2013

Репутация: нет
Всего: 1



Цитата(math64 @  11.9.2014,  08:04 Найти цитируемый пост)
Раз Вы настаиваете на использовании const, то должны требовоать const и с указателями:


Верно.
Я так и делаю.

Более того: квалификатор const контекстно зависимый.
Есть ситуации, когда он нужен лишь программисту (и компилятор сделает доп. проверки)

А есть ситуации,когда компилятору критично, квалифицировано ли имя const ?


Я спрашивал ребят на собеседовании: прочтите вслух этот прототип:

Код

void foo(const some& obj);


Многие, очень многие ребята говорили: функция foo, которая ничего не возвращает, в качестве аргумента принимает константную ссылку.

Это не верно. На языке с++ у ссылок вообще нет квалификатора. 

Код

some val;
const some& ref = val;
coust<< std::is_const< decltype(ref) >::val


Результат - ноль.

Если вы попробуете его сделать на шаблонах, то CL (компилятор вижал студии) сделает предупреждение - квалификатор ссылок будет проигнорирован и вы получите мутабельную ссылку.
Компилятор gcc сделает тоже самое, только не сделает предупреждение.

Ну так вот, если вы сделаете:

Код

cout<< std::is_same<void(int), void(const int)>::value


То в качестве результата, вы увидите 1.

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


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

Мне это видится настолько простым, что мне кажется - ну я просто повторяюсь, а добавить нечего.


Мне очень жаль, что господа влезли в этот диалог, предварительно не прочитав мой диалог с господином Baldina

Добавлено @ 17:03
Цитата(math64 @  11.9.2014,  10:01 Найти цитируемый пост)
Предлагаю компромисс: использовать const только для параметров, имеющих значения по умолчанию.


Противоречит здравому смыслу.

Добавлено @ 17:04
Цитата(math64 @  11.9.2014,  08:04 Найти цитируемый пост)
разве что кто-то найдёт пример вредности такого использования const в С++.


Найдите. Если сможете. Только их нет.

Добавлено @ 17:07
Цитата(math64 @  11.9.2014,  08:04 Найти цитируемый пост)
Такое компилятор вроде тоже сожрёт (не проверял), хотя смысла особого нет:


Так вы проверьте, а потом уже говорите.

Я проверял - квалификатор будет полностью проигнорирован. (cl)

Это сообщение отредактировал(а) Lukkoye - 12.9.2014, 17:09
PM MAIL   Вверх
sQu1rr
Дата 12.9.2014, 18:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 597
Регистрация: 11.11.2008
Где: london

Репутация: 3
Всего: 13



Цитата(Lukkoye @  12.9.2014,  17:03 Найти цитируемый пост)
Противоречит здравому смыслу.

Не понимаете шуток и намека, как бы пора закруглится (не лично вам, а всем обсуждающим), так как холивар на тему кому как нравится писать код ни к чему хорошему никогда не приводил.
ЗЫ может и не так понял, и мр. math64 действительно считает, что нужно использовать константы с дефолтными параметрами smile
PM MAIL Skype GTalk   Вверх
Страницы: (3) [Все] 1 2 3 
Ответ в темуСоздание новой темы Создание опроса
Правила форума "C/C++: Для новичков"
JackYF
bsa

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

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

  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, JackYF, bsa.

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Для новичков | Следующая тема »


 




[ Время генерации скрипта: 0.1701 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.