![]() |
Модераторы: Daevaorn |
![]() ![]() ![]() |
|
BlHol |
|
||||
![]() Шустрый ![]() Профиль Группа: Участник Сообщений: 126 Регистрация: 26.11.2005 Репутация: нет Всего: нет |
Спасибо.
Теперь обнаружил следующий парадокс: Из той программулины со switch-case привожу 2 case:
Вот, когда в таком виде компиляю, выдается ошибка case bypasses initialization of local variable. А когда я каждый блок в case замыкаю в {...}
ошибка пропадает. Почкму так происходит? Заранее спасибо. С уважением. |
||||
|
|||||
zkv |
|
|||
![]() ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 2133 Регистрация: 23.7.2006 Где: Санкт-Петербург Репутация: 26 Всего: 92 |
что написано, то и значит. Нельзя перескакивать через объявление переменной, а когда ставите скобки, то делаете переменные локальные в новом "маленьком" блоке, таким образом не может возникнут "непонятных" для компилятора ситуаций. |
|||
|
||||
BlHol |
|
|||
![]() Шустрый ![]() Профиль Группа: Участник Сообщений: 126 Регистрация: 26.11.2005 Репутация: нет Всего: нет |
Я дико извиняюсь. Суть ошибки мне понятна. Мне непонятно, где я перескочил через инициализацию локальной переменной... Я имею в виду в том куске, который я привел выше.
Заранее спасибо. С уважением. |
|||
|
||||
zkv |
|
||||
![]() ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 2133 Регистрация: 23.7.2006 Где: Санкт-Петербург Репутация: 26 Всего: 92 |
BlHol, в вашем куске, простите, и черт ногу сломит. Следует как то поудобнее все это дело организовать, километровые кэйсы - не лучший стиль
![]()
обратите внимание на строку 6 вашего листинга.
Вопросы есть? ![]() |
||||
|
|||||
BlHol |
|
|||
![]() Шустрый ![]() Профиль Группа: Участник Сообщений: 126 Регистрация: 26.11.2005 Репутация: нет Всего: нет |
Задачка так стоит. Организовать выбор варианта (открыть на запись, открыть на чтение, выход). И в зависимости от этого, соответственно открывать файл. Каким образом это можно еще реализовать. Не через if-else же?
Я правильно понимаю, что в case не должно быть объявления переменной и ее инициализации? Кстати, ошибка выкидывается на второй case. Первый, несмотря на то, что там тоже присутствует fstream fbin(......), благополучно проглатывается. Заранее спасибо. Это сообщение отредактировал(а) BlHol - 18.4.2007, 09:29 |
|||
|
||||
zkv |
|
||||
![]() ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 2133 Регистрация: 23.7.2006 Где: Санкт-Петербург Репутация: 26 Всего: 92 |
первое, самое простое, что приходит в голову:
Заметь, в таком случае подобным ошибкам просто нет места, да и читается проще. попробуй убрать второй кейс - компилятор скажет, что все ок, проблема возникает, если существует возможность "перепрыгнуть" через инициализацию переменной (с goto такая же фигня вроде), сейчас я не возьмусь объяснять почему тут такое строгое ограничение (боюсь соврать). Думаю если чел сталкивается с подобной ошибкой, то у него явно проблемы с проектированием ![]() ![]() |
||||
|
|||||
dizzy1984 |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 675 Регистрация: 15.2.2007 Репутация: 3 Всего: 25 |
В конктетном случае организовать работу можно, например, так.
Определите fstream fbin до switch©, затем использйте fbin.Open Либо определите fstream fbin(path, ios::binary | ios::out |ios::in) до свича, это определение позволит впоследствии как писать так и читать из файла.
Правильно. Хотя нет, пардон, в первой ветке case можно определять переменные. Спасобо zkv за разъяснение. Видимо компилятор приостанавливает проверку подобных ситуаций после появления первой. Попробуйте исправить второй case и посмотреть проглотит ли компилятор после этого первый. А на счет причины такого ограничения, может мне кто-нибудь напомнит почему нельзя перескакивать через определения локальных переменных. Я смутно что-то помню про проблемы с деструкторами, но не могу сообразить. Это сообщение отредактировал(а) dizzy1984 - 18.4.2007, 10:29 |
|||
|
||||
BlHol |
|
|||
![]() Шустрый ![]() Профиль Группа: Участник Сообщений: 126 Регистрация: 26.11.2005 Репутация: нет Всего: нет |
Т.е. банально реализовать чтение, запись в разных функциях?
|
|||
|
||||
dizzy1984 |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 675 Регистрация: 15.2.2007 Репутация: 3 Всего: 25 |
Разобрался.
Проблема заключается в том, что мы теоретически можем использовать fbin в ветке case 2:, т.к все ветки switch относятся к одной области видимости. Если fbin будет исользоваться в case 2: и управление попадет туда минуя case 1, то переменная fbin будет использоваться будучи не проинициализированной. Это не запрещено в с, но запрещено в с++. В этом свете сказанное ранее немного меняется. Объявлять переменные можно только в последней ветке switch (default), т.к перепрыгнуть через ние уже никак не получится. Остается неясным момент почему компилятор не может осущестить проверку на факт использования fbin в case2 и при отсутствии такового не выдавать ошибку. Добавлено через 5 минут и 34 секунды Если у тебя разница между этими ветками заключается только в том будут ли писаться или читаться данные, то однозначно тебе нужно писать фунцию с флагом определяющим действие в качестве аргумента. |
|||
|
||||
BlHol |
|
|||
![]() Шустрый ![]() Профиль Группа: Участник Сообщений: 126 Регистрация: 26.11.2005 Репутация: нет Всего: нет |
Ну, не совсем так. У меня же в 1-м и во 2-м case разные переменные. В1-м fbin, во 2-м f_bin_2. Т.о. если мы даже и проскакиваем 1-й case, то f_bin и не инициализируется и не используется. Почему тогда нельзя?
По поводу функции. Я не совсем понял, флаг передавать в виде аргумента? Заранее спасибо. |
|||
|
||||
dizzy1984 |
|
||||||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 675 Регистрация: 15.2.2007 Репутация: 3 Всего: 25 |
Мне это и самому не поняно. По-видимому, это просто строгость компилятора, который старается исключить даже те ситауции, которые могут быть опасными просто потенциально. Возможно, он является блюстителем чистоты кода, ведь все прыжки через иициализации переменных, это нехорошая практика, всгда можно переписать такой код, разместив переменые до прыжка. Пример Функция осществляющая запись либо перезапись (???)
Программа и свич, который ее использует
Ты хотел написать что файл будет перезаписан? Тогда это будет "Warning! Used file will be rewritten" Хорошая практика программирования говорит, что любую повторяющуюся последовательность действий, которая встречается более 2-х раз нужно оформлять в виде отдельной функции. Сам я правда ленюсь это делать и жду 3-х повторений. |
||||||
|
|||||||
BlHol |
|
|||
![]() Шустрый ![]() Профиль Группа: Участник Сообщений: 126 Регистрация: 26.11.2005 Репутация: нет Всего: нет |
В принципе, понятно, только тут во всех case разные варианты открытия файла. В данном случае, не все ли равно, реализую ли я это в 3-х функциях или распихаю по case?
Заранее спасибо. |
|||
|
||||
dizzy1984 |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 675 Регистрация: 15.2.2007 Репутация: 3 Всего: 25 |
Очень может быть что вы сможете обойтись одной функцией для всех case.
Если хотите услышать мое мнение объясните программу целиком. Конечно, нет смысла писать 3 функции для 3-х case. Нужно делать подобное если хотя бы 2-а из них логически можно объединить в 1-н. Тогда вместо 3-х функции для 3-х case будут 2 функции. Разница вот в чем : 1. дальнейшие модификации повторяющихся фрагментов вам придется делать либо для каждого case, либо для одной функции с параметрами. 2. если ваш код предстоит разбирать другому программисту он должен потратить время чтобы понять логику работы программы. Он сделает это быстрее если в программе будет мало повторяющегося кода, а все похожее по смыслу будет сведено в несколько функций. |
|||
|
||||
nickless |
|
||||
![]() Гентозавр ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 2976 Регистрация: 29.8.2005 Где: Germany Репутация: 19 Всего: 181 |
default не обязательно последняя ветка, его можно и в начале поставить. Переменные можно объявлят где угодно, но желательно обрамить каждый case в блок, чтобы исключить перепрыгивание инициализации и соответствующие варнинги.
Я бы сделал функции хотя бы для улучшения читабельности. Вообще рекомендуется не писать функции длинее одного экрана, а в твоём коде один только switch на 86 строк! У меня например столько в экран не помещается, в результате нужно протоянно скроллить вверх-вниз, чтобы посмотреть чем же заканчивается этот switch, сколько там веток итд. Да и вообще форматировать код очень важно. -------------------- ![]() Real men don't use backups, they post their stuff on a public ftp server and let the rest of the world make copies - Linus Torvalds |
||||
|
|||||
dizzy1984 |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 675 Регистрация: 15.2.2007 Репутация: 3 Всего: 25 |
||||
|
||||
![]() ![]() ![]() |
Правила форума "С++:Общие вопросы" | |
|
Добро пожаловать!
Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn |
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей) | |
0 Пользователей: | |
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема » |
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |