Форум программистов, компьютерный форум, киберфорум
Наши страницы

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

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

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

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

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

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

C++
1
2
3
4
5
6
7
8
9
10
int main () {
 int p;
 
 //есть ли способ сделать так, чтобы 
 //компилятор  ругался на присвоение
 //(ЛЮБЫМ способом) переменной p
 //определённого значения, например, 7?
 returtn 0;
 
}
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++
Как заставить программу запуститься в спрятанном режиме, чтобы её можно было найти только в Дистептчере задач во вкладке процессы и...

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

Компьютер невероятно быстрая и в тоже время необычайно тупая машина. Не помню в какой книге вычитал(точно учебник Си++).
0
taras atavin
3570 / 1753 / 91
Регистрация: 24.11.2009
Сообщений: 27,619
30.12.2012, 13:13 #17
Цитата Сообщение от ~OhMyGodSoLong~ Посмотреть сообщение
Вот только функция не делает то, что должна делать.
С чьей точки зрения должна? Она делает то, как написана, то есть то, что должна делать с точки зрения компилятора. А то, что "программист" не понимает смысла собственных действий, к делу не относится. Чтоб не допускать семантических ошибок, надо думать, что пишешь, и знать язык, а синтаксически функция правильна.
0
kravam
быдлокодер
1702 / 889 / 45
Регистрация: 04.06.2008
Сообщений: 5,498
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) Вот и ошибка компиляции. Как-то так.
0
taras atavin
3570 / 1753 / 91
Регистрация: 24.11.2009
Сообщений: 27,619
30.12.2012, 15:08 #19
Цитата Сообщение от kravam Посмотреть сообщение
Смотрим перегруженный оператор = класса T
2) Определяем, что параметром к этому оператору может идти какой-нибудь класс T1
3) Пытаемся перетипизировать (T1)8, а не получается
4) Вот и ошибка компиляции. Как-то так.
Конструктор не работает на этапе компиляции и как ты не проверяй параметр в конструкторе, компилятор не сможет понять, чего ты хотел. Он может только формально перевести текст в код, но не проанализировать логику на предмет того, какую сгенерить "пользовательскую" гугломессагу. Он понимает лишь алгоритмы, но не их назначение. Единственное, как можно конкретное значение запретить при компиляции, это сделать его не представимым, например, сократить разрядность до 3-х бит, тогда диапазон представимых чисел от ноля до семи, восемь в него не входит.

Добавлено через 1 минуту
Можно, конечно, каждое разрешённое значение закейсовать, но это перенос проблемы и её усугубление, а не решение: можно ошибиться при написании миллиардов кейсов и компилятор это проглотит.
0
ForEveR
В астрале
Эксперт С++
7983 / 4742 / 321
Регистрация: 24.06.2010
Сообщений: 10,545
Завершенные тесты: 3
30.12.2012, 15:50 #20
taras atavin, Это знаете-ли неправда. constexpr конструкторы никто не отменял.
0
taras atavin
3570 / 1753 / 91
Регистрация: 24.11.2009
Сообщений: 27,619
30.12.2012, 15:55 #21
Объясни, как компилятор поймёт, для чего этот конструктор предназначен?
0
Jupiter
Каратель
Эксперт С++
6560 / 3981 / 227
Регистрация: 26.03.2010
Сообщений: 9,273
Записей в блоге: 1
Завершенные тесты: 2
30.12.2012, 20:06 #22
Цитата Сообщение от kravam Посмотреть сообщение
1) Смотрим перегруженный оператор = класса T
2) Определяем, что параметром к этому оператору может идти какой-нибудь класс T1
3) Пытаемся перетипизировать (T1)8, а не получается
4) Вот и ошибка компиляции. Как-то так.
что-то не пойму что вас сейчас не устраивает когда все так и есть
0
kravam
быдлокодер
1702 / 889 / 45
Регистрация: 04.06.2008
Сообщений: 5,498
30.12.2012, 21:34  [ТС] #23
Цитата Сообщение от Jupiter Посмотреть сообщение
3) Пытаемся перетипизировать (T1)8, а не получается
эту операцию он пытается сделать для всех чисел как я понимаю. А должно быть, чтобы (T1)8 было некорректным приведением типов, а (T1)4 корректным; тогда значение 4 компилятор пропустит, а значение 8 нет.
0
OhMyGodSoLong
~ Эврика! ~
1244 / 993 / 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 не будет полноценных макросов.
0
taras atavin
3570 / 1753 / 91
Регистрация: 24.11.2009
Сообщений: 27,619
31.12.2012, 09:24 #25
А макросы чем помогут? Ошибку в самом запрете/разрешении значения компилятор проглотит всё равно.
0
OhMyGodSoLong
~ Эврика! ~
1244 / 993 / 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% проверок будут выполняться в рантайме.
0
Evg
Эксперт CАвтор FAQ
18261 / 6386 / 440
Регистрация: 30.03.2009
Сообщений: 17,671
Записей в блоге: 28
31.12.2012, 11:37 #27
Цитата Сообщение от kravam Посмотреть сообщение
Мне не даёт покоя разговор с одним программистом, имевший место быть несколько лет назад. Тот сказал, что он так кодит, что у него неправильный код просто-напросто не компилится, а я не стал уточнять. Многое я бы отдал, чтобы вернуться к тому разговору!
Основная масса способов, которая растёт преимущественно из Си++ - это способы испоганить исходник на ровном месте. Не надо гнаться за тем, чтобы идиотскими способами ловить ошибки на этапе компиляции. На этапе компиляции надо ловить то, что ловится просто. А сложные вещи лучше пытаться ловить в рантайме, но максимально близко к точке возникновения ошибки. В очередной раз наблюдаю у тебя повышение уровня осознания, так что можешь попробовать почитать тут: http://www.cyberforum.ru/blogs/18334/blog104.html (правда до конца так и не написано)
0
31.12.2012, 11:37
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++
Проблема состоит в том, что при решении задач матфизики трудно поставить условия так, чтобы не возникала численная неустойчивость. При...


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

Или воспользуйтесь поиском по форуму:
27
Ответ Создать тему
Опции темы

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