|
Почетный модератор
7393 / 2639 / 281
Регистрация: 29.07.2006
Сообщений: 13,696
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||
Циклы for. Проблема объявления/инициализации31.08.2008, 03:42. Показов 9986. Ответов 23
Метки нет (Все метки)
Эх, так и придется создавать новую тему. А то, блин, интересно ж...
Итак, я тут в недавней теме утверждал, что блок инициализации цикла for является внешним по отношению к его внутреннему блоку (блоку команд, то бишь). CheshireСat's евангелие не соглашается со мной С чего возник базар? С того, что нужно, все-таки, выяснить чем же особенны такие конструкции (с объявлением переменных в заголовке цикла):
Уберем инициализацию объявление из заголовка.
Теперь можно провести небольшой эксперимент:
J = 10 I = 10. А теперь засунем новую переменную В БЛОК цикла:
J = 1 I = 10 И последнее:
J = 10 I = 1 Ах ты батюшки. Не обнулилась. А не сделала она этого потому что объявлена как вне блока цикла. На уровень выше самого блока команд цикла. И в исполнении цикла строка int i = 0 никакого участия не принимает. Абсолютно. Если совсем скучно, то можно заглянуть в "Бархатный путь С++":
Дабы, это выглядело, как настоящая тема, вопрос: Где я ошибся? Кто, что думает по этому поводу? Может, в объявлении/инициализации в заголовке цикла нет ничего, на что стоило бы обращать внимание? P. S. вот именно, блин, поэтому такое использование может принести сюрпризы (это ж какую конструкцию надо придумать), если не знать, как оно работает. Я не утверждаю, что так делать нельзя, или плохо. Так делать можно. Ничего страшного в этом нет абсолютно. Просто надо иметь ввиду. P. P. S. CheshireСat, что на это скажет твое евангелие? Добавлено через 28 минут 25 секунд Кстати, как мне сразу в голову не пришло. Если мы уберем int i; внешний и оставим только в заголовке то:
В итоге мы получили ту же внешнюю по отношению к блоку операторов цикла переменную. Даже с аналогичным адресом То есть, на уровне ассемблера код не меняется. Тот же самый листинг получается из:
3
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||
| 31.08.2008, 03:42 | |
|
Ответы с готовыми решениями:
23
Правила объявления инициализации
|
|
296 / 56 / 5
Регистрация: 22.05.2008
Сообщений: 788
|
|
| 31.08.2008, 12:40 | |
|
+1 за полезную тему. довольно интересный материал
ЗЫ дисассемблирование рулит
0
|
|
|
2924 / 1274 / 114
Регистрация: 27.05.2008
Сообщений: 3,465
|
|||||||
| 31.08.2008, 15:21 | |||||||
|
Спасибо Vourhey за столь любопытное исследование.
Но, у меня вопрос первый: а зачем нам дизассемблирование? Тот код, который мы получаем в дизассемблере, говорит только лишь о том, что вот так вот это реализовано в данном конкретном компиляторе на данной конкретной ОС... и ничего не говорит о том, что произойдет на другом компиляторе и/или другой ОС/железе. С моей точки зрения, представляют интерес два вопроса: 1. Что говорит Стандарт - т.е., что должно быть? 2. Как реально ведут себя некоторые современные компиляторы, - т.е. насколько точно они соответствуют Стандарту, либо не соответствуют. Что есть на самом деле? Итак: 1. Стандарт определяет поведение и область видимости управляющей переменной исчерпывающим образом:
2. Из доступных мне компиляторов: (В последние годы я работаю в основном с Microsoft Visual C++....) а). MS visual C++ 6.0 (1998) не соответствует Стандарту: область видимости управляющей переменной цикла простирается от заголовка цикла до конца объемлющего блока; т.е., код вида
б). MS Visual C++ 7.0 (2002) и 7.1 (2003) занимают промежуточную позицию: по умолчанию включен старый режим, ключ компилятора /Zc:forScope позволяет включить режим точного соответствия Стандарту. в). MS Visual C++ 8.0 (2005) и последующие по умолчанию точно соответствуют Стандарту; это означает, что приведенный код просто не скомпилируется. Впрочем, все тот же ключ forScope позволяет обеспечить таки совместимость со старым унаследованным кодом и скомпилировать приведенный фрагмент. г). GCC 4.2.2 (Linux) точно соответствует Стандарту.
0
|
|||||||
|
Почетный модератор
7393 / 2639 / 281
Регистрация: 29.07.2006
Сообщений: 13,696
|
||||||
| 31.08.2008, 15:28 [ТС] | ||||||
|
Стоп, стоп, стоп. Я не слова не сказал про область видимости переменной. Заметь.
Я объяснил, что не так с этим объявлением. По-моему, вполне доступно. С учетом того, что компилеров куча и настроить их можно по-разному код нужно писать безопаснее. А объявление в заголовке цикла это сделать не позволяет на 100%. Что и требовалось доказать. Такое написание вполне нормально, но есть и свои минусы. P. S. мне особо без разницы, что где написано, пока я не увижу. Дизассемблерный листинг показывает лучше всего. P. P. S. ты можешь компилить в студии, а я, например, в G++ (версия 3.1) могу скомпилить такой код:
Повторюсь. Я не говорю, что это неправильно и так нельзя делать. Это нормально, и так вполне нормально кодить. Просто в жизни все бывает. И полностью рабочий код в одном случае может сработать не так, как хотелось в другом. Надо это учитывать. Так что, будем объективны. Код нужно писать безопасней, если возможно.
0
|
||||||
|
10 / 10 / 2
Регистрация: 18.08.2008
Сообщений: 127
|
||||||||||||||||
| 31.08.2008, 23:06 | ||||||||||||||||
Вот еще интересно , а если в цикле цикл.
0
|
||||||||||||||||
|
296 / 56 / 5
Регистрация: 22.05.2008
Сообщений: 788
|
|
| 31.08.2008, 23:20 | |
|
почему скорее всего? почему не проверили? эх.... наверное придется мне разбираться с линуксовыми дизасемблерами
и что ето за скобки квадратные такие?
0
|
|
|
Почетный модератор
7393 / 2639 / 281
Регистрация: 29.07.2006
Сообщений: 13,696
|
|
| 31.08.2008, 23:35 [ТС] | |
|
Примеров можно кучу придумать, мне влом их в gdb загонять
![]() Главное, подтверждается то, что такое использование в редких случаях, но все же может быть неоднозначным. Что может вызвать трудности.
0
|
|
|
296 / 56 / 5
Регистрация: 22.05.2008
Сообщений: 788
|
|
| 31.08.2008, 23:42 | |
|
зачем gdb? gcc\g++ с ключом -S рулет
upd извиняюсь, тут немного не то
0
|
|
|
2924 / 1274 / 114
Регистрация: 27.05.2008
Сообщений: 3,465
|
||
| 01.09.2008, 12:09 | ||
|
Далее. Если приведенный пример кода компилируется в g++ (а он действительно компилируется!), то я не вполне понимаю, почему. Поскольку таким образом g++ нарушает требования п.6.5.3 clause 3 Стандарта. Кстати, ни MSVC++ 8.0, ни Comeau, ни компилятор Interstron - этот код не компилируют. Конечно же, код нужно писать безопасным. Но - с моей точки зрения (IMHO - имею мнение, хрен оспоришь!) код нужно писать прежде всего по Стандарту. А если какой-то компилятор отклоняется от Стандарта.... что ж, очень плохо, - либо нужно менять компилятор, либо изобретать костыли и подпорки; и, разумеется, не забыть эти костыли прокомментировать!
0
|
||
|
Почетный модератор
7393 / 2639 / 281
Регистрация: 29.07.2006
Сообщений: 13,696
|
|||||||||||||||||
| 01.09.2008, 13:14 [ТС] | |||||||||||||||||
Таким же макаром. Пусть не скомпилируют, а шестой билдер и g++ скомпилируют. А то что, на более низком уровне:
К тому, что написав так:
Пиши по стандарту. Стандарты есть везде. А еще есть реальность... P. S. VC++ поддерживает стандарты какие-то еще ? Батюшки...новости... У мелкомягких вообще нет никаких стандартов. Они сами себе стандрат P. P. S. Те, кто считают, что у С++ есть общий на всех, признанный стандарт ошибаются. Его нет. Есть даже разные редакции стандартов. Так что говорить, что один компилирует правильно, другой нет - необдуманно. Надо кодить обдуманно, чтобы избежать подводных камней. А не идти тупо напролом с одной редакцией одного из стандартов...
0
|
|||||||||||||||||
|
9 / 7 / 3
Регистрация: 30.08.2008
Сообщений: 120
|
|||||||
| 03.09.2008, 03:52 | |||||||
|
Прокомпелировав этот код:
а qwone все-таки пишет на Visual Studio 6 как раз там та такая ошибка и будет, и опять повторяю, что в Visual Studio 2005-2008 нет!!!
0
|
|||||||
|
Почетный модератор
7393 / 2639 / 281
Регистрация: 29.07.2006
Сообщений: 13,696
|
|
| 03.09.2008, 11:53 [ТС] | |
|
Sined, "сам пробовал" - не аргумент. Приведи дизассемблерный листинг, чтобы доказать, что разные вещи получатся на низком уровне. Тогда поверю. Это раз.
Два. У меня наоборот на 2008 не компилится, а в билдере и g++ легко. P. S. твои споры еще раз доказывают, что стандарта С++ единого нет.
0
|
|
|
9 / 7 / 3
Регистрация: 30.08.2008
Сообщений: 120
|
||
| 03.09.2008, 12:22 | ||
|
Нет, подожди, подожди, ты пишеш, что компилирование происходит в Visual Studio 2008, вот приме твоего описания:
0
|
||
|
Почетный модератор
7393 / 2639 / 281
Регистрация: 29.07.2006
Сообщений: 13,696
|
||||||
| 03.09.2008, 12:35 [ТС] | ||||||
|
Вот блин, а...
Я же написал, что
Блин, как я по-твоему листинг дизассемблерный приводил, если код выше (в твоем сообщении) не компилится?! Сам, что ли, писал? ![]() P. S. понимаешь ли...кроме компилеров cl.exe есть еще много...
0
|
||||||
|
9 / 7 / 3
Регистрация: 30.08.2008
Сообщений: 120
|
|
| 03.09.2008, 13:25 | |
|
Я написал, что не компилируется в Visual Studio 6 (шестая версия) а в Visual Studio 2005
компилируется, а за Visual Studio 2008 тебе нечего сказать не могу так как его у меня нет. Но я не думаю, что в 2005 и 2008 будут такие различия. "Но" это не довод но всетаки в Visual Studio 6 и в Visual Studio 2005 есть.
0
|
|
|
Почетный модератор
7393 / 2639 / 281
Регистрация: 29.07.2006
Сообщений: 13,696
|
|
| 03.09.2008, 13:25 [ТС] | |
|
Что там есть?
Я не пойму, че ты доказать хочешь, но не можешь...
0
|
|
|
9 / 7 / 3
Регистрация: 30.08.2008
Сообщений: 120
|
||||||
| 03.09.2008, 13:47 | ||||||
|
Почему сразу хочу, но не могу.
Ты пишешь по первому листингу дизасемблера, что две переменные являються вне цыкла. А ты попробуй такой код: ![]()
0
|
||||||
|
2924 / 1274 / 114
Регистрация: 27.05.2008
Сообщений: 3,465
|
||
| 03.09.2008, 13:49 | ||
|
1. существование Стандарта языка как регламентирующего документа - как должно быть, 2. различные реализации этого Стандарта независимыми производителями компиляторов, - что есть на самом деле? Реализации могут отклоняться от требований Стандарта; насколько мне известно, нет ни одного компилятора, на все 100% соответствующего Стандарту.
0
|
||
|
9 / 7 / 3
Регистрация: 30.08.2008
Сообщений: 120
|
||
| 03.09.2008, 14:00 | ||
|
Так его, так... ![]() Потому как Произвидитель Visual Studio 6 и Visual Studio 2005 один и тот-же, а стандарта нет.
0
|
||
|
Почетный модератор
7393 / 2639 / 281
Регистрация: 29.07.2006
Сообщений: 13,696
|
||||||||
| 03.09.2008, 14:09 [ТС] | ||||||||
|
CheshireCat, нет, я не путаю эти вещи. Единого стандарта С++ нет. Параллельно существуют несколько стандартов. Да короче, че я тут с тобой спорю... Даже, если бы и был, то практика уже все показала и подтвердила, что толку от них. Но его нет. Есть, например: iso14882:2003/1998. Они существуют параллельно. Я молчу про различные их редакции. Если ни один компилер на 100% не поддерживает ни один стандарт, то тем более, этот код становится менее безопасным. Добавлено через 2 минуты 16 секунд Sined, вот именно, что если нет стандарта единого, этор еще больше уменьшает безопасность приведенного мною кода. Короче, ты тут споришь, а сам ни одного аргумента не привел. Хочешь настоящий стандарт увидеть? Иди и учи ada. Тогда с тобой поговорим. И ассемблер заодно... Ты, по-моему, в бронепоезде сидишь... g++ даже ошибку покажет умнее:
![]() Еще раз повторю, что откомпилированный:
Сейчас основные два стандарта поддерживаются. Никто не отменял ничего. Так что, "написание по стандарту" в данном случае есть фигня. Так как, и та и эта запись идут по стандарту. Просто в одном случае я буду писать, если знаю, что никому не буду давать свой код, не буду его портировать. В противном случае (если я знаю, что придется портировать, разными компилерами компилить, на разных системах тестить), то мой мозг будет знать, что для данной ситуации, лучше объявить переменную вне цикла. Так я гарантированно задам для нее namespace.
2
|
||||||||
| 03.09.2008, 14:09 | |
|
Помогаю со студенческими работами здесь
20
Когда выделяется память под переменные - во время объявления или инициализации Проблема с ADWORDS: при активности кампании объявления не показываются..
Циклы с условием, циклы с переменной, вложенные циклы
Искать еще темы с ответами Или воспользуйтесь поиском по форуму: |
|
Новые блоги и статьи
|
|||
|
изучаю kubernetes
lagorue 13.01.2026
А пригодятся-ли мне знания kubernetes в России?
|
сукцессия микоризы: основная теория в виде двух уравнений.
anaschu 11.01.2026
https:/ / rutube. ru/ video/ 7a537f578d808e67a3c6fd818a44a5c4/
|
WordPad для Windows 11
Jel 10.01.2026
WordPad для Windows 11
— это приложение, которое восстанавливает классический текстовый редактор WordPad в операционной системе Windows 11. После того как Microsoft исключила WordPad из. . .
|
Classic Notepad for Windows 11
Jel 10.01.2026
Old Classic Notepad for Windows 11
Приложение для Windows 11, позволяющее пользователям вернуть классическую версию текстового редактора «Блокнот» из Windows 10. Программа предоставляет более. . .
|
|
Почему дизайн решает?
Neotwalker 09.01.2026
В современном мире, где конкуренция за внимание потребителя достигла пика, дизайн становится мощным инструментом для успеха бренда. Это не просто красивый внешний вид продукта или сайта — это. . .
|
Модель микоризы: классовый агентный подход 3
anaschu 06.01.2026
aa0a7f55b50dd51c5ec569d2d10c54f6/
O1rJuneU_ls
https:/ / vkvideo. ru/ video-115721503_456239114
|
Owen Logic: О недопустимости использования связки «аналоговый ПИД» + RegKZR
ФедосеевПавел 06.01.2026
Owen Logic: О недопустимости использования связки «аналоговый ПИД» + RegKZR
ВВЕДЕНИЕ
Введу сокращения:
аналоговый ПИД — ПИД регулятор с управляющим выходом в виде числа в диапазоне от 0% до. . .
|
Модель микоризы: классовый агентный подход 2
anaschu 06.01.2026
репозиторий https:/ / github. com/ shumilovas/ fungi
ветка по-частям.
коммит Create переделка под биомассу. txt
вход sc, но sm считается внутри мицелия. кстати, обьем тоже должен там считаться. . . .
|