Форум программистов, компьютерный форум CyberForum.ru

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
 
Рейтинг: Рейтинг темы: голосов - 9, средняя оценка - 4.89
kravam
быдлокодер
1694 / 881 / 44
Регистрация: 04.06.2008
Сообщений: 5,441
#1

Как заставить компилятор не компилить неправильную программу? - C++

29.12.2012, 14:56. Просмотров 1137. Ответов 26
Метки нет (Все метки)

Мне не даёт покоя разговор с одним программистом, имевший место быть несколько лет назад. Тот сказал, что он так кодит, что у него неправильный код просто-напросто не компилится, а я не стал уточнять. Многое я бы отдал, чтобы вернуться к тому разговору!

Ясно дело, что даже если это и правда, то правда условная. Компилятор же не знает, что нужно человеку. Тем не мене, может есть какие-то способы ограничить поведение (предотвратить его) программы на стадии компиляции при синтаксически правильном коде? Будем здесь их обсуждать. Начнём с простого.

C++
1
2
3
4
5
6
7
8
9
10
int main () {
 int p;
 
 //есть ли способ сделать так, чтобы 
 //компилятор  ругался на присвоение
 //(ЛЮБЫМ способом) переменной p
 //определённого значения, например, 7?
 returtn 0;
 
}
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
29.12.2012, 14:56
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Как заставить компилятор не компилить неправильную программу? (C++):

есть ли компилятор для андроида? на планшете хочу компилить - C++
или процессор в планшете не поддержит мою идею?

Как компилить программу с libjpeg? - C++
Я не понимаю, как компилить программу с libjpeg, если я использую Visual Studio. Г* командная строка - не находит nmake.

Как заставить компилятор выводить имя файла? - C++
Всем привет! Компилятор GCC. Из Readme: Проблема вот в чем. Создал батник, для экономии действий, следующего содержания: ...

Как заставить компилятор давать имена символам, соответствующие названиям функций? - C++
Здравствуйте! Пишу динамическую библиотеку, в которой имплементирую функцию run() - эта функция должна вызываться потом сторонним...

Компилить программу сразу из CMD - C++
Приветствую. У меня такая задача, собрать необходимую библиотеку для С++, которая бы позволила компилить программу сразу из CMD при...

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

Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Croessmah
Модератор
Эксперт CЭксперт С++
13132 / 7395 / 828
Регистрация: 27.09.2012
Сообщений: 18,222
Записей в блоге: 3
Завершенные тесты: 1
30.12.2012, 12:47 #16
Цитата Сообщение от ~OhMyGodSoLong~ Посмотреть сообщение
Вот это неправильный код, реализующий умножение двух чисел:
Код правильный, точнее валидный но компилятор же не знает что нужно программисту. Тут логика не та и это уже не заботы компилятора. В конце концов, если клавиатура сломана, он еще и печатать должен за программиста?

Компьютер невероятно быстрая и в тоже время необычайно тупая машина. Не помню в какой книге вычитал(точно учебник Си++).
taras atavin
Ушёл с форума.
3569 / 1752 / 91
Регистрация: 24.11.2009
Сообщений: 27,619
30.12.2012, 13:13 #17
Цитата Сообщение от ~OhMyGodSoLong~ Посмотреть сообщение
Вот только функция не делает то, что должна делать.
С чьей точки зрения должна? Она делает то, как написана, то есть то, что должна делать с точки зрения компилятора. А то, что "программист" не понимает смысла собственных действий, к делу не относится. Чтоб не допускать семантических ошибок, надо думать, что пишешь, и знать язык, а синтаксически функция правильна.
kravam
быдлокодер
1694 / 881 / 44
Регистрация: 04.06.2008
Сообщений: 5,441
30.12.2012, 14:33  [ТС] #18
Так-то из области фантастики задача, но хоть ЧТО-ТО мы ведь можем проконтролировать? Щас вот изучаю C# так там прямо сказано- они частично ошибки времени выполнения делаю ошибками компиляции с помощью хитрой какой-то перетипизации

+++++++++++++++++++++++++++++++++++++++++++

Ну вот допустим я пишу так (ошибочно!)
C++
1
int p= 8;
То есть я не должен присваивать переменной p значение 8, а я присвоил. Это же можно как-то проконтролировать? Например использовать не переменнную типа int, а создать класс, в котором инкапсулировать переменную int; и сделать так чтобы в правой части была тоже не переменная int, а переменная какого-нибудь хитрого класса. И чтобы объекты этого класса не могли принимать значение 8

Ну то есть чтобы был контроль типов. Чтобы логика компилятора была примерно такая:
C++
1
T p= 8;
1) Смотрим перегруженный оператор = класса T
2) Определяем, что параметром к этому оператору может идти какой-нибудь класс T1
3) Пытаемся перетипизировать (T1)8, а не получается
4) Вот и ошибка компиляции. Как-то так.
taras atavin
Ушёл с форума.
3569 / 1752 / 91
Регистрация: 24.11.2009
Сообщений: 27,619
30.12.2012, 15:08 #19
Цитата Сообщение от kravam Посмотреть сообщение
Смотрим перегруженный оператор = класса T
2) Определяем, что параметром к этому оператору может идти какой-нибудь класс T1
3) Пытаемся перетипизировать (T1)8, а не получается
4) Вот и ошибка компиляции. Как-то так.
Конструктор не работает на этапе компиляции и как ты не проверяй параметр в конструкторе, компилятор не сможет понять, чего ты хотел. Он может только формально перевести текст в код, но не проанализировать логику на предмет того, какую сгенерить "пользовательскую" гугломессагу. Он понимает лишь алгоритмы, но не их назначение. Единственное, как можно конкретное значение запретить при компиляции, это сделать его не представимым, например, сократить разрядность до 3-х бит, тогда диапазон представимых чисел от ноля до семи, восемь в него не входит.

Добавлено через 1 минуту
Можно, конечно, каждое разрешённое значение закейсовать, но это перенос проблемы и её усугубление, а не решение: можно ошибиться при написании миллиардов кейсов и компилятор это проглотит.
ForEveR
В астрале
Эксперт С++
7970 / 4732 / 321
Регистрация: 24.06.2010
Сообщений: 10,541
Завершенные тесты: 3
30.12.2012, 15:50 #20
taras atavin, Это знаете-ли неправда. constexpr конструкторы никто не отменял.
taras atavin
Ушёл с форума.
3569 / 1752 / 91
Регистрация: 24.11.2009
Сообщений: 27,619
30.12.2012, 15:55 #21
Объясни, как компилятор поймёт, для чего этот конструктор предназначен?
Jupiter
Каратель
Эксперт С++
6553 / 3973 / 226
Регистрация: 26.03.2010
Сообщений: 9,273
Записей в блоге: 1
Завершенные тесты: 2
30.12.2012, 20:06 #22
Цитата Сообщение от kravam Посмотреть сообщение
1) Смотрим перегруженный оператор = класса T
2) Определяем, что параметром к этому оператору может идти какой-нибудь класс T1
3) Пытаемся перетипизировать (T1)8, а не получается
4) Вот и ошибка компиляции. Как-то так.
что-то не пойму что вас сейчас не устраивает когда все так и есть
kravam
быдлокодер
1694 / 881 / 44
Регистрация: 04.06.2008
Сообщений: 5,441
30.12.2012, 21:34  [ТС] #23
Цитата Сообщение от Jupiter Посмотреть сообщение
3) Пытаемся перетипизировать (T1)8, а не получается
эту операцию он пытается сделать для всех чисел как я понимаю. А должно быть, чтобы (T1)8 было некорректным приведением типов, а (T1)4 корректным; тогда значение 4 компилятор пропустит, а значение 8 нет.
OhMyGodSoLong
~ Эврика! ~
1243 / 992 / 42
Регистрация: 24.07.2012
Сообщений: 2,002
30.12.2012, 22:45 #24
Вот проблема в том, что constexpr говорит компилятору, что "это можно использовать при compile-time-вычислениях", но он позволяет использовать определяемое не только в compile-time. Поэтому static_assert в конструктор или приводилку типов не влепить, если только не задавать значения действительно только в compile-time — шаблонами: писать какой-нибудь T1<8>. Так что в принципе можно изнасиловать синтаксис и сделать compile-time-проверку для инициализации каким-то int_<8> и runtime-проверку на обычные инты. Но толку-то?

И альтернативы этому не появится, пока в каком-нибудь очередном C++17 не будет полноценных макросов.
taras atavin
Ушёл с форума.
3569 / 1752 / 91
Регистрация: 24.11.2009
Сообщений: 27,619
31.12.2012, 09:24 #25
А макросы чем помогут? Ошибку в самом запрете/разрешении значения компилятор проглотит всё равно.
OhMyGodSoLong
~ Эврика! ~
1243 / 992 / 42
Регистрация: 24.07.2012
Сообщений: 2,002
31.12.2012, 11:20 #26
Да они тоже не особо альтернатива. Но они могут обломать компиляцию, если значение не подходит. Просто для int_<8>-то хватит и примитивного #define I(v) int_<v>(), но не для более сложных объектов, где пригодится гарантированно compile-time constexpr, но не с таким сногсшибательным синтаксисом как у темплейтов. Это даже могут быть не макросы, а именно просто compile-time-only constexpr (кодогенерацию при компиляции мейнстрим чё-то пока не заценил).

Но вопрос "на кой хрен" остаётся в силе. Конечно, можно сделать так, чтобы писать Constrained<int, Or<InRange<2, 42>, Not<Even>, Equals<67, 98>>, но ведь проблему зависимости типов это не решит. Эту хрень можно будет гарантированно скастовать только к инту. Остальные касты будут выполняться вместе с проверками в рантайме, а значит, особо нет толку от написания всех ограничений на шаблонах (которые как бы намекают, что проверки на валидность кастов должны выполняться лишь при компиляции), если всё равно 99% проверок будут выполняться в рантайме.
Evg
Эксперт CАвтор FAQ
17619 / 5843 / 375
Регистрация: 30.03.2009
Сообщений: 16,118
Записей в блоге: 26
31.12.2012, 11:37 #27
Цитата Сообщение от kravam Посмотреть сообщение
Мне не даёт покоя разговор с одним программистом, имевший место быть несколько лет назад. Тот сказал, что он так кодит, что у него неправильный код просто-напросто не компилится, а я не стал уточнять. Многое я бы отдал, чтобы вернуться к тому разговору!
Основная масса способов, которая растёт преимущественно из Си++ - это способы испоганить исходник на ровном месте. Не надо гнаться за тем, чтобы идиотскими способами ловить ошибки на этапе компиляции. На этапе компиляции надо ловить то, что ловится просто. А сложные вещи лучше пытаться ловить в рантайме, но максимально близко к точке возникновения ошибки. В очередной раз наблюдаю у тебя повышение уровня осознания, так что можешь попробовать почитать тут: http://www.cyberforum.ru/blogs/18334/blog104.html (правда до конца так и не написано)
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
31.12.2012, 11:37
Привет! Вот еще темы с ответами:

Как компилить x64? - C++
У меня почему то sizeof(size_t)==4, а система windows 7 x64. Как с этим бороться?

Как заставить программу управлять программами? - C++
Подскажите как заставить программу управлять программами, в случае если необходимо применить много раз одну и ту же операцию из стандартной...

Как заставить программу выбирать наибольшие число? - C++
Нужно было сделать программу которая запрашивает 5 чисел и выбирает наибольшие и наименьшие число. С запросом чисел все понятно, но вот как...

Как заставить программу завершаться при делении на ноль? - C++
Проблема состоит в том, что при решении задач матфизики трудно поставить условия так, чтобы не возникала численная неустойчивость. При...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
Yandex
Объявления
31.12.2012, 11:37
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru